Release 1.3.0
This commit is contained in:
		
							parent
							
								
									63e918e79a
								
							
						
					
					
						commit
						837528ad9c
					
				| @ -5,6 +5,10 @@ | |||||||
| ### NEXT_VERSION_DESCRIPTION_BEGIN | ### NEXT_VERSION_DESCRIPTION_BEGIN | ||||||
| ### NEXT_VERSION_DESCRIPTION_END | ### NEXT_VERSION_DESCRIPTION_END | ||||||
| 
 | 
 | ||||||
|  | ## [1.3.0] (22-12-2023) | ||||||
|  | 
 | ||||||
|  | * Update payment method via Sber | ||||||
|  | 
 | ||||||
| ## [1.2.2] (29-09-2023) | ## [1.2.2] (29-09-2023) | ||||||
| 
 | 
 | ||||||
| * Fix unnecessary_non_null_assertion warnings in test | * Fix unnecessary_non_null_assertion warnings in test | ||||||
|  | |||||||
							
								
								
									
										55
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								README.md
									
									
									
									
									
								
							| @ -46,14 +46,16 @@ source 'https://git.yoomoney.ru/scm/sdk/cocoa-pod-specs.git' | |||||||
| </array> | </array> | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Решение проблем подключения: | ## Решение проблем подключения/сборки | ||||||
| 
 | 
 | ||||||
| А. В случае когда `pod install` завершается с ошибкой – попробуйте команду `pod update YooKassaPayments` | 1. pod install` завершается с ошибкой | ||||||
| 
 | 
 | ||||||
| B. В некоторых сложных случаях рекомендуем сбросить кэш cocoapods. Это можно сделать несколькими способам. | * Попробуйте команду `pod update YooKassaPayments` | ||||||
|  | 
 | ||||||
|  | * В некоторых сложных случаях рекомендуем сбросить кэш cocoapods. Это можно сделать несколькими способам. | ||||||
| 
 | 
 | ||||||
|    Вариант 1: выполнить набор команд для сброса кэша для пода YooKassaPayments и его зависимостей: |    Вариант 1: выполнить набор команд для сброса кэша для пода YooKassaPayments и его зависимостей: | ||||||
|                ``` |                ```bash | ||||||
|                pod cache clean FunctionalSwift --all |                pod cache clean FunctionalSwift --all | ||||||
|                pod cache clean MoneyAuth  --all |                pod cache clean MoneyAuth  --all | ||||||
|                pod cache clean ThreatMetrixAdapter  --all |                pod cache clean ThreatMetrixAdapter  --all | ||||||
| @ -69,6 +71,11 @@ B. В некоторых сложных случаях рекомендуем с | |||||||
|                |                | ||||||
|    Далее рекомендуем выполнить `flutter clean`, `pod clean` и `pod deintegrate YOUR_PROJECT_NAME.xcodeproj` |    Далее рекомендуем выполнить `flutter clean`, `pod clean` и `pod deintegrate YOUR_PROJECT_NAME.xcodeproj` | ||||||
|    для последущей чистой установки командой `pod install` |    для последущей чистой установки командой `pod install` | ||||||
|  |     | ||||||
|  | 2. При сборке получили ошибку `xcode no such module '__ObjC'` | ||||||
|  | 
 | ||||||
|  | * Откройте ios проект в Xcode, выберите target `Runner`, перейдите в найтройки Build Settings и выставьте флаг `Build Libraries for Distribution` в `NO`. Для project `Runner` проделайте тоже самое — Project Runner -> Build Settings -> установите Build Libraries for Distribution в NO. | ||||||
|  | Далее в Xcode Product -> Clean build folder.., и также очистите содержимое DerivedData | ||||||
| 
 | 
 | ||||||
| ## Быстрая интеграция | ## Быстрая интеграция | ||||||
| 
 | 
 | ||||||
| @ -101,8 +108,10 @@ var result = await YookassaPaymentsFlutter.tokenization(tokenizationModuleInputD | |||||||
| 
 | 
 | ||||||
| ```dart | ```dart | ||||||
| var result = await YookassaPaymentsFlutter.tokenization(tokenizationModuleInputData); | var result = await YookassaPaymentsFlutter.tokenization(tokenizationModuleInputData); | ||||||
| var token = result.token; | if (result is SuccessTokenizationResult) { | ||||||
| var paymentMethodType = result.paymentMethodType; |     var token = result.token; | ||||||
|  |     var paymentMethodType = result.paymentMethodType; | ||||||
|  | } | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| 4. Закройте модуль SDK и отправьте токен в вашу систему. Затем [создайте платеж](https://yookassa.ru/developers/api#create_payment) по API ЮKassa, в параметре `payment_token` передайте токен, полученный в SDK. Способ подтверждения при создании платежа зависит от способа оплаты, который выбрал пользователь. Он приходит вместе с токеном в `paymentMethodType`. | 4. Закройте модуль SDK и отправьте токен в вашу систему. Затем [создайте платеж](https://yookassa.ru/developers/api#create_payment) по API ЮKassa, в параметре `payment_token` передайте токен, полученный в SDK. Способ подтверждения при создании платежа зависит от способа оплаты, который выбрал пользователь. Он приходит вместе с токеном в `paymentMethodType`. | ||||||
| @ -110,7 +119,10 @@ var paymentMethodType = result.paymentMethodType; | |||||||
| 5. Подтверждение платежа. При необходимости система может запросить процесс подтверждения платежа, при котором пользователь подтверждает транзакцию с помощью сторонних сервисов. Плагин поддерживает два типа подтверждения платежа - 3Dsecure (при оплате банковской картой) и App2App сценарий (при оплате через SberPay). Ссылку вы получаете от бекенда Кассы после проведения платежа на шаге 4. | 5. Подтверждение платежа. При необходимости система может запросить процесс подтверждения платежа, при котором пользователь подтверждает транзакцию с помощью сторонних сервисов. Плагин поддерживает два типа подтверждения платежа - 3Dsecure (при оплате банковской картой) и App2App сценарий (при оплате через SberPay). Ссылку вы получаете от бекенда Кассы после проведения платежа на шаге 4. | ||||||
| 
 | 
 | ||||||
| ```dart | ```dart | ||||||
| await YookassaPaymentsFlutter.confirmation("3ds / App2App ссылка", result.paymentMethodType); | var clientApplicationKey = "<Ключ для клиентских приложений>"; | ||||||
|  | var shopId = "<Идентификатор магазина в ЮKassa)>"; | ||||||
|  | 
 | ||||||
|  | await YookassaPaymentsFlutter.confirmation(confirmationUrl, PaymentMethod.sbp, clientApplicationKey, shopId); | ||||||
| // обработайте результат подтверждения на следущей строке (после возврата управления) | // обработайте результат подтверждения на следущей строке (после возврата управления) | ||||||
| ``` | ``` | ||||||
| Завершение процесса `YookassaPaymentsFlutter.confirmation` не несет информацию о том, что пользователь фактически подтвердил платеж (он мог его пропустить). После получения результата рекомендуем запросить статус платежа. | Завершение процесса `YookassaPaymentsFlutter.confirmation` не несет информацию о том, что пользователь фактически подтвердил платеж (он мог его пропустить). После получения результата рекомендуем запросить статус платежа. | ||||||
| @ -122,8 +134,6 @@ await YookassaPaymentsFlutter.confirmation("3ds / App2App ссылка", result. | |||||||
| `.yooMoney` — ЮMoney (платежи из кошелька или привязанной картой)\ | `.yooMoney` — ЮMoney (платежи из кошелька или привязанной картой)\ | ||||||
| `.bankCard` — банковская карта (карты можно сканировать)\ | `.bankCard` — банковская карта (карты можно сканировать)\ | ||||||
| `.sberbank` — SberPay (с подтверждением через приложение Сбербанк Онлайн, если оно установленно, иначе с подтверждением по смс)\ | `.sberbank` — SberPay (с подтверждением через приложение Сбербанк Онлайн, если оно установленно, иначе с подтверждением по смс)\ | ||||||
| `.applePay` — Apple Pay\ |  | ||||||
| `.googlePay` — Google Pay |  | ||||||
| `.sbp` - СБП\ | `.sbp` - СБП\ | ||||||
| 
 | 
 | ||||||
| ## Настройка способов оплаты | ## Настройка способов оплаты | ||||||
| @ -153,16 +163,6 @@ if (<Условие для ЮMoney>) { | |||||||
|     paymentMethodTypes.add(PaymentMethod.yooMoney); |     paymentMethodTypes.add(PaymentMethod.yooMoney); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| if <Условие для Apple Pay> { |  | ||||||
|     // Добавляем в paymentMethodTypes элемент `.applePay` |  | ||||||
|     paymentMethodTypes.insert(.applePay) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| if <Условие для Google Pay> { |  | ||||||
|     // Добавляем в paymentMethodTypes элемент `.googlePay` |  | ||||||
|     paymentMethodTypes.insert(.googlePay) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| if <Условие для СБП> { | if <Условие для СБП> { | ||||||
|     // Добавляем в paymentMethodTypes элемент `.sbp` |     // Добавляем в paymentMethodTypes элемент `.sbp` | ||||||
|     paymentMethodTypes.insert(.sbp) |     paymentMethodTypes.insert(.sbp) | ||||||
| @ -437,8 +437,9 @@ android { | |||||||
| 
 | 
 | ||||||
| ```dart | ```dart | ||||||
| var clientApplicationKey = "<Ключ для клиентских приложений>"; | var clientApplicationKey = "<Ключ для клиентских приложений>"; | ||||||
|  | var shopId = "<Идентификатор магазина в ЮKassa)>"; | ||||||
| 
 | 
 | ||||||
| await YookassaPaymentsFlutter.confirmation(confirmationUrl, PaymentMethod.sbp, clientApplicationKey); | await YookassaPaymentsFlutter.confirmation(confirmationUrl, PaymentMethod.sbp, clientApplicationKey, shopId); | ||||||
| ) | ) | ||||||
| ``` | ``` | ||||||
| `confirmationUrl` вы получите в ответе от API ЮKassa при [создании платежа](https://yookassa.ru/developers/api#create_payment); он имеет вид   "https://qr.nspk.ru/id?type=&bank=&sum=&cur=&crc=&payment_id=" | `confirmationUrl` вы получите в ответе от API ЮKassa при [создании платежа](https://yookassa.ru/developers/api#create_payment); он имеет вид   "https://qr.nspk.ru/id?type=&bank=&sum=&cur=&crc=&payment_id=" | ||||||
| @ -535,8 +536,8 @@ func didFinishConfirmation(paymentMethodType: PaymentMethodType) { | |||||||
| ### Amount | ### Amount | ||||||
| 
 | 
 | ||||||
| | Параметр | Тип      | Описание | | | Параметр | Тип      | Описание | | ||||||
| | -------- | -------- | -------- | | | -------- |----------| -------- | | ||||||
| | value    | Double   | Сумма платежа | | | value    | String   | Сумма платежа | | ||||||
| | currency | Currency | Валюта платежа | | | currency | Currency | Валюта платежа | | ||||||
| 
 | 
 | ||||||
| ### Currency | ### Currency | ||||||
| @ -566,12 +567,15 @@ func didFinishConfirmation(paymentMethodType: PaymentMethodType) { | |||||||
| 
 | 
 | ||||||
| Если вы хотите использовать нашу реализацию подтверждения платежа, не закрывайте модуль SDK после получения токена.\ | Если вы хотите использовать нашу реализацию подтверждения платежа, не закрывайте модуль SDK после получения токена.\ | ||||||
| Отправьте токен на ваш сервер и после успешной оплаты закройте модуль.\ | Отправьте токен на ваш сервер и после успешной оплаты закройте модуль.\ | ||||||
| Если ваш сервер сообщил о необходимости подтверждения платежа (т.е. платёж пришёл со статусом `pending`), вызовите метод `confirmation(confirmationUrl, paymentMethodType)`. | Если ваш сервер сообщил о необходимости подтверждения платежа (т.е. платёж пришёл со статусом `pending`), вызовите метод `confirmation(confirmationUrl, paymentMethodType, clientApplicationKey, shopId)`. | ||||||
| 
 | 
 | ||||||
| Пример кода: | Пример кода: | ||||||
| 
 | 
 | ||||||
| ```dart | ```dart | ||||||
| await YookassaPaymentsFlutter.confirmation(confirmationUrl, result.paymentMethodType); | var clientApplicationKey = "<Ключ для клиентских приложений>"; | ||||||
|  | var shopId = "<Идентификатор магазина в ЮKassa)>"; | ||||||
|  | 
 | ||||||
|  | await YookassaPaymentsFlutter.confirmation(confirmationUrl, PaymentMethod.sbp, clientApplicationKey, shopId); | ||||||
| ) | ) | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| @ -582,8 +586,9 @@ await YookassaPaymentsFlutter.confirmation(confirmationUrl, result.paymentMethod | |||||||
| ```dart | ```dart | ||||||
| 
 | 
 | ||||||
| var clientApplicationKey = "<Ключ для клиентских приложений>"; | var clientApplicationKey = "<Ключ для клиентских приложений>"; | ||||||
|  | var shopId = "<Идентификатор магазина в ЮKassa)>"; | ||||||
| 
 | 
 | ||||||
| await YookassaPaymentsFlutter.confirmation(confirmationUrl, result.paymentMethodType, clientApplicationKey); | await YookassaPaymentsFlutter.confirmation(confirmationUrl, result.paymentMethodType, clientApplicationKey, shopId); | ||||||
| ) | ) | ||||||
| ``` | ``` | ||||||
| `confirmationUrl` вы получите в ответе от API ЮKassa при [создании платежа](https://yookassa.ru/developers/api#create_payment); он имеет вид   "https://qr.nspk.ru/id?type=&bank=&sum=&cur=&crc=&payment_id=" | `confirmationUrl` вы получите в ответе от API ЮKassa при [создании платежа](https://yookassa.ru/developers/api#create_payment); он имеет вид   "https://qr.nspk.ru/id?type=&bank=&sum=&cur=&crc=&payment_id=" | ||||||
|  | |||||||
							
								
								
									
										229
									
								
								Sberpay via SberSDK.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										229
									
								
								Sberpay via SberSDK.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,229 @@ | |||||||
|  | # Проведение платежа через SberSDK | ||||||
|  | 
 | ||||||
|  | Функциональность доступна ограниченному кругу наших клиентов, так как находится в тестировании. Чтобы попасть в число ранних пользователей необходимо связаться со своим менеджером и запросить доступ. | ||||||
|  | 
 | ||||||
|  | - [Настройка оплаты через SberPay с нуля](#чистая-настройка) | ||||||
|  | - [Переход со старой версии SberPay](#переход-на-новую-версию) | ||||||
|  | 
 | ||||||
|  | С помощью SDK можно провести и подтвердить платеж через актуальное приложение Сбербанка, если оно установленно, иначе с подтверждением по смс. | ||||||
|  | 
 | ||||||
|  | ## <a name="чистая-настройка"></a> Настройка оплаты через SberPay с нуля | ||||||
|  | 
 | ||||||
|  | (!) Далее описание настройки метода `SberPay`, если ранее вы его не использовали. | ||||||
|  | 
 | ||||||
|  | В `TokenizationModuleInputData` необходимо передавать `applicationScheme` – схема для возврата в приложение после успешной оплаты с помощью `SberPay` в приложении Сбербанка. | ||||||
|  | 
 | ||||||
|  | Пример `applicationScheme`: | ||||||
|  | 
 | ||||||
|  | ```dart | ||||||
|  | let tokenizationModuleInputData = TokenizationModuleInputData( | ||||||
|  |     ... | ||||||
|  |     applicationScheme: "examplescheme://" | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Чтобы провести платёж: | ||||||
|  | 
 | ||||||
|  | ### 1. При создании `TokenizationModuleInputData` передайте значение `PaymentMethod.sberbank` в `tokenizationSettings`. | ||||||
|  | 
 | ||||||
|  | ```dart | ||||||
|  | var tokenizationSettings = const TokenizationSettings(PaymentMethodTypes([ | ||||||
|  |     PaymentMethod.sberbank | ||||||
|  | ])); | ||||||
|  | 
 | ||||||
|  | var tokenizationModuleInputData = | ||||||
|  |           TokenizationModuleInputData(clientApplicationKey: "<Ключ для клиентских приложений>", | ||||||
|  |                                       title: "Космические объекты", | ||||||
|  |                                       subtitle: "Комета повышенной яркости, период обращения — 112 лет", | ||||||
|  |                                       amount: Amount(value: 999.9, currency: Currency.rub), | ||||||
|  |                                       shopId: "<Идентификатор магазина в ЮKassa)>", | ||||||
|  |                                       savePaymentMethod: SavePaymentMethod.on, | ||||||
|  |                                       tokenizationSettings: tokenizationSettings); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### 2. Запустите процесс токенизации, передав TokenizationModuleInputData | ||||||
|  | 
 | ||||||
|  | ```dart | ||||||
|  | var result = await YookassaPaymentsFlutter.tokenization(tokenizationModuleInputData); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### 3. Получите токен | ||||||
|  | 
 | ||||||
|  | ```dart | ||||||
|  | var result = await YookassaPaymentsFlutter.tokenization(tokenizationModuleInputData); | ||||||
|  | if (result is SuccessTokenizationResult) { | ||||||
|  |     var token = result.token; | ||||||
|  |     var paymentMethodType = result.paymentMethodType; | ||||||
|  | } else if (result is ErrorTokenizationResult) { | ||||||
|  |     // обработайте ошибку | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### 4. [Создайте платеж](https://yookassa.ru/developers/api#create_payment) с токеном по API ЮKassa. | ||||||
|  | 
 | ||||||
|  | ## Для подтверждения платежа через приложение Сбербанка: | ||||||
|  | 
 | ||||||
|  | ### 1. Добавьте уникальную схему диплинка | ||||||
|  | 
 | ||||||
|  | Для **iOS** в `Info.plist` добавьте следующие строки: | ||||||
|  | 
 | ||||||
|  | ```plistbase | ||||||
|  | <key>CFBundleURLTypes</key> | ||||||
|  | <array> | ||||||
|  |     <dict> | ||||||
|  |         <key>CFBundleTypeRole</key> | ||||||
|  |         <string>Editor</string> | ||||||
|  |         <key>CFBundleURLName</key> | ||||||
|  |         <string>${BUNDLE_ID}</string> | ||||||
|  |         <key>CFBundleURLSchemes</key> | ||||||
|  |         <array> | ||||||
|  |             <string>examplescheme</string> | ||||||
|  |         </array> | ||||||
|  |     </dict> | ||||||
|  | </array> | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Для **android** в ваш файл build.gradle в блок android.defaultConfig добавьте строку | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | android { | ||||||
|  |     defaultConfig { | ||||||
|  |         resValue "string", "ym_app_scheme", "exampleapp" | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | или добавить в ваш strings.xml строку вида: | ||||||
|  | ``` | ||||||
|  | <resources> | ||||||
|  |     <string name="ym_app_scheme" translatable="false">exampleapp</string> | ||||||
|  | </resources> | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | где `examplescheme` - схема для открытия вашего приложения, которую вы указали в `applicationScheme` при создании `TokenizationModuleInputData`. Через эту схему будет открываться ваше приложение после успешной оплаты с помощью `SberPay`. | ||||||
|  | 
 | ||||||
|  | ### 2. Для android подключите библиотеку профилирования формата .aar | ||||||
|  | 
 | ||||||
|  | Попросите у менеджера по подключению библиотеку профилирования формата .aar. Создайте папку libs в модуле где подключаете sdk и добавьте туда файл aar-файл. В build.gradle того же модуля в dependencies добавьте: | ||||||
|  | ```groovy | ||||||
|  | dependencies { | ||||||
|  |     implementation fileTree(dir: "libs", include: ["*.aar"]) | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### 3. Добавить в `Info.plist` новые схемы для обращения в сервисам Сбера | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | <key>LSApplicationQueriesSchemes</key> | ||||||
|  | <array> | ||||||
|  |     <string>sbolidexternallogin</string> | ||||||
|  |     <string>sberbankidexternallogin</string>    | ||||||
|  | </array> | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | и расширенные настройки для http-соединений к сервисам Сбера | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | <key>NSAppTransportSecurity</key> | ||||||
|  | <dict> | ||||||
|  |     <key>NSExceptionDomains</key> | ||||||
|  |     <dict> | ||||||
|  |     <key>gate1.spaymentsplus.ru</key> | ||||||
|  |     <dict> | ||||||
|  |        <key>NSExceptionAllowsInsecureHTTPLoads</key> | ||||||
|  |        <true/> | ||||||
|  |     </dict> | ||||||
|  |     <key>ift.gate2.spaymentsplus.ru</key> | ||||||
|  |     <dict> | ||||||
|  |        <key>NSExceptionAllowsInsecureHTTPLoads</key> | ||||||
|  |        <true/> | ||||||
|  |     </dict> | ||||||
|  |     <key>cms-res.online.sberbank.ru</key> | ||||||
|  |        <dict> | ||||||
|  |            <key>NSExceptionAllowsInsecureHTTPLoads</key> | ||||||
|  |            <true/> | ||||||
|  |        </dict> | ||||||
|  |     </dict> | ||||||
|  | </dict> | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### 4. Подтверждение платежа. При необходимости система может запросить процесс подтверждения платежа, при котором пользователь подтверждает транзакцию с помощью сервисов Сбера. Ссылку вы получаете от бекенда Кассы после проведения платежа на шаге 4. | ||||||
|  | 
 | ||||||
|  | ```dart | ||||||
|  | var clientApplicationKey = "<Ключ для клиентских приложений>"; | ||||||
|  | var shopId = "<Идентификатор магазина в ЮKassa)>"; | ||||||
|  | 
 | ||||||
|  | await YookassaPaymentsFlutter.confirmation(confirmationUrl, PaymentMethod.sbp, clientApplicationKey, shopId); | ||||||
|  | // обработайте результат подтверждения на следущей строке (после возврата управления) | ||||||
|  | ``` | ||||||
|  | Завершение процесса `YookassaPaymentsFlutter.confirmation` не несет информацию о том, что пользователь фактически подтвердил платеж (он мог его пропустить). После получения результата рекомендуем запросить статус платежа. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## <a name="переход-на-новую-версию"></a> Переход на новую версию SberPay | ||||||
|  | 
 | ||||||
|  | (!) Далее описание настройки новой версии метода `SberPay`, если ранее вы его уже использовали. | ||||||
|  | 
 | ||||||
|  | Сценарий оплаты через `Sberpay` теперь происходит не в мобильном приложения, а через встроенное Sber SDK. | ||||||
|  | 
 | ||||||
|  | ### Список изменений для android: | ||||||
|  | 
 | ||||||
|  | Попросите у менеджера по подключению библиотеку формата `.aar`. | ||||||
|  |   Создайте папку libs в модуле где подключаете sdk и добавьте туда файл `B.aar`. В build.gradle того же модуля в dependencies добавьте: | ||||||
|  | ```groovy | ||||||
|  | dependencies { | ||||||
|  |     implementation fileTree(dir: "libs", include: ["*.aar"]) | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Также необходимо в метод `YookassaPaymentsFlutter.confirmation` передать параметр `clientApplicationKey` - ключ для клиентских приложений из личного кабинета ЮKassa ([раздел Настройки — Ключи API](https://yookassa.ru/my/api-keys-settings)); | ||||||
|  | 
 | ||||||
|  | ```dart | ||||||
|  | var clientApplicationKey = "<Ключ для клиентских приложений>"; | ||||||
|  | var shopId = "<Идентификатор магазина в ЮKassa)>"; | ||||||
|  | 
 | ||||||
|  | await YookassaPaymentsFlutter.confirmation(confirmationUrl, PaymentMethod.sbp, clientApplicationKey, shopId); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Список изменений для iOS: | ||||||
|  | 
 | ||||||
|  | 1. В вашем файле `Info.plist` заменить схему для обращений в сервисам Сбера | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | <key>LSApplicationQueriesSchemes</key> | ||||||
|  | <array> | ||||||
|  |     <string>sberpay</string>  | ||||||
|  | </array> | ||||||
|  | ``` | ||||||
|  | на обновленную версию | ||||||
|  | ``` | ||||||
|  | <key>LSApplicationQueriesSchemes</key> | ||||||
|  | <array> | ||||||
|  |     <string>sbolidexternallogin</string> | ||||||
|  |     <string>sberbankidexternallogin</string>    | ||||||
|  | </array> | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 2. Добавить расширенные настройки для http-соединений к сервисам Сбера | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | <key>NSAppTransportSecurity</key> | ||||||
|  | <dict> | ||||||
|  |     <key>NSExceptionDomains</key> | ||||||
|  |     <dict> | ||||||
|  |     <key>gate1.spaymentsplus.ru</key> | ||||||
|  |     <dict> | ||||||
|  |        <key>NSExceptionAllowsInsecureHTTPLoads</key> | ||||||
|  |        <true/> | ||||||
|  |     </dict> | ||||||
|  |     <key>ift.gate2.spaymentsplus.ru</key> | ||||||
|  |     <dict> | ||||||
|  |        <key>NSExceptionAllowsInsecureHTTPLoads</key> | ||||||
|  |        <true/> | ||||||
|  |     </dict> | ||||||
|  |     <key>cms-res.online.sberbank.ru</key> | ||||||
|  |        <dict> | ||||||
|  |            <key>NSExceptionAllowsInsecureHTTPLoads</key> | ||||||
|  |            <true/> | ||||||
|  |        </dict> | ||||||
|  |     </dict> | ||||||
|  | </dict> | ||||||
|  | ``` | ||||||
| @ -1,14 +1,14 @@ | |||||||
| group 'ru.yoomoney.sdk.kassa.payments.flutter' | group 'ru.yoomoney.sdk.kassa.payments.flutter' | ||||||
| 
 | 
 | ||||||
| buildscript { | buildscript { | ||||||
|     ext.kotlin_version = '1.7.10' |     ext.kotlin_version = '1.8.22' | ||||||
|     repositories { |     repositories { | ||||||
|         google() |         google() | ||||||
|         mavenCentral() |         mavenCentral() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     dependencies { |     dependencies { | ||||||
|         classpath 'com.android.tools.build:gradle:7.3.0' |         classpath 'com.android.tools.build:gradle:7.4.1' | ||||||
|         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" |         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -52,5 +52,9 @@ android { | |||||||
| 
 | 
 | ||||||
| dependencies { | dependencies { | ||||||
|     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" |     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" | ||||||
|     implementation 'ru.yoomoney.sdk.kassa.payments:yookassa-android-sdk:6.7.1' |     implementation 'ru.yoomoney.sdk.kassa.payments:yookassa-android-sdk:6.9.2' | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | configurations.implementation { | ||||||
|  |     exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8' | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME | |||||||
| distributionPath=wrapper/dists | distributionPath=wrapper/dists | ||||||
| zipStoreBase=GRADLE_USER_HOME | zipStoreBase=GRADLE_USER_HOME | ||||||
| zipStorePath=wrapper/dists | zipStorePath=wrapper/dists | ||||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip | ||||||
|  | |||||||
| @ -79,13 +79,15 @@ class YookassaPaymentsFlutterPlugin: FlutterPlugin, MethodCallHandler, ActivityA | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     val url = data["url"] as String |     val url = data["url"] as String | ||||||
|     val clientApplicationKey = data["clientApplicationKey"] as String? |     val clientApplicationKey = data["clientApplicationKey"] as String | ||||||
|  |     val shopId = data["shopId"] as String | ||||||
| 
 | 
 | ||||||
|     val intent: Intent = Checkout.createConfirmationIntent( |     val intent: Intent = Checkout.createConfirmationIntent( | ||||||
|       context = context, |       context = context, | ||||||
|       confirmationUrl = url, |       confirmationUrl = url, | ||||||
|       clientApplicationKey = clientApplicationKey, |       clientApplicationKey = clientApplicationKey, | ||||||
|       paymentMethodType = paymentMethod |       paymentMethodType = paymentMethod, | ||||||
|  |       shopId = shopId | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     activity.startActivityForResult(intent, REQUEST_CODE_CONFIRMATION) |     activity.startActivityForResult(intent, REQUEST_CODE_CONFIRMATION) | ||||||
| @ -173,7 +175,7 @@ class YookassaPaymentsFlutterPlugin: FlutterPlugin, MethodCallHandler, ActivityA | |||||||
| 
 | 
 | ||||||
| private fun PaymentParameters(data: Map<String, Object>): PaymentParameters { | private fun PaymentParameters(data: Map<String, Object>): PaymentParameters { | ||||||
|   val amountMap: HashMap<String, Object> = data["amount"] as HashMap<String, Object> |   val amountMap: HashMap<String, Object> = data["amount"] as HashMap<String, Object> | ||||||
|   val amount = Amount(BigDecimal(amountMap["value"] as Double), Currency.getInstance(amountMap["currency"] as String)) |   val amount = Amount(BigDecimal(amountMap["value"] as String), Currency.getInstance(amountMap["currency"] as String)) | ||||||
| 
 | 
 | ||||||
|   val clientApplicationKey = data["clientApplicationKey"] as String |   val clientApplicationKey = data["clientApplicationKey"] as String | ||||||
|   val title = data["title"] as String |   val title = data["title"] as String | ||||||
| @ -242,7 +244,7 @@ private fun GooglePayParameters(data: Map<String, Object>): GooglePayParameters | |||||||
| 
 | 
 | ||||||
| private fun SavedBankCardPaymentParameters(data: Map<String, Object>): SavedBankCardPaymentParameters { | private fun SavedBankCardPaymentParameters(data: Map<String, Object>): SavedBankCardPaymentParameters { | ||||||
|   val amountMap: HashMap<String, Object> = data["amount"] as HashMap<String, Object> |   val amountMap: HashMap<String, Object> = data["amount"] as HashMap<String, Object> | ||||||
|   val amount = Amount(BigDecimal(amountMap["value"] as Double), Currency.getInstance(amountMap["currency"] as String)) |   val amount = Amount(BigDecimal(amountMap["value"] as String), Currency.getInstance(amountMap["currency"] as String)) | ||||||
|   val title = data["title"] as String |   val title = data["title"] as String | ||||||
|   val subtitle = data["subtitle"] as String |   val subtitle = data["subtitle"] as String | ||||||
|   val clientApplicationKey = data["clientApplicationKey"] as String |   val clientApplicationKey = data["clientApplicationKey"] as String | ||||||
|  | |||||||
| @ -1,12 +1,12 @@ | |||||||
| buildscript { | buildscript { | ||||||
|     ext.kotlin_version = '1.5.0' |     ext.kotlin_version = '1.8.22' | ||||||
|     repositories { |     repositories { | ||||||
|         google() |         google() | ||||||
|         mavenCentral() |         mavenCentral() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     dependencies { |     dependencies { | ||||||
|         classpath 'com.android.tools.build:gradle:7.0.3' |         classpath 'com.android.tools.build:gradle:7.4.1' | ||||||
|         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" |         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,11 +1,13 @@ | |||||||
| PODS: | PODS: | ||||||
|   - Flutter (1.0.0) |   - Flutter (1.0.0) | ||||||
|   - FunctionalSwift (1.8.0) |   - FunctionalSwift (2.0.6) | ||||||
|   - MobileSdk (2.0.0) |   - MobileSdk (2.0.0) | ||||||
|   - MoneyAuth (6.1.0): |   - MoneyAuth (10.2.1): | ||||||
|     - FunctionalSwift (~> 1.8) |     - FunctionalSwift (~> 2.0) | ||||||
|     - YooMoneyCoreApi (~> 2.1) |     - YooMoneyCoreApi (~> 3.0) | ||||||
|     - YooMoneyUI (~> 6.0) |     - YooMoneySessionProfiler (~> 5.0) | ||||||
|  |     - YooMoneyUI (~> 7.0) | ||||||
|  |   - SPaySDK (1.0.9) | ||||||
|   - YandexMobileMetrica/Dynamic (4.5.2): |   - YandexMobileMetrica/Dynamic (4.5.2): | ||||||
|     - YandexMobileMetrica/Dynamic/Core (= 4.5.2) |     - YandexMobileMetrica/Dynamic/Core (= 4.5.2) | ||||||
|     - YandexMobileMetrica/Dynamic/Crashes (= 4.5.2) |     - YandexMobileMetrica/Dynamic/Crashes (= 4.5.2) | ||||||
| @ -14,26 +16,27 @@ PODS: | |||||||
|     - YandexMobileMetrica/Dynamic/Core |     - YandexMobileMetrica/Dynamic/Core | ||||||
|   - yookassa_payments_flutter (0.0.1): |   - yookassa_payments_flutter (0.0.1): | ||||||
|     - Flutter |     - Flutter | ||||||
|     - YooKassaPayments (= 6.12.0) |     - YooKassaPayments (= 6.14.0) | ||||||
|   - YooKassaPayments (6.12.0): |   - YooKassaPayments (6.14.0): | ||||||
|     - MoneyAuth (~> 6.1.0) |     - MoneyAuth (~> 10.2.1) | ||||||
|  |     - SPaySDK (~> 1.0.8) | ||||||
|     - YandexMobileMetrica/Dynamic (>= 3.0) |     - YandexMobileMetrica/Dynamic (>= 3.0) | ||||||
|     - YooKassaPaymentsApi (~> 2.20.1) |     - YooKassaPaymentsApi (~> 2.21.2) | ||||||
|     - YooKassaWalletApi (~> 2.3.1) |     - YooKassaWalletApi (~> 2.3.1) | ||||||
|     - YooMoneyCoreApi (~> 2.1.0) |     - YooMoneyCoreApi (~> 3.0) | ||||||
|     - YooMoneySessionProfiler (~> 5.0.1) |     - YooMoneySessionProfiler (~> 5.0.1) | ||||||
|     - YooMoneyUI (~> 6.2.0) |     - YooMoneyUI (~> 7.3.1) | ||||||
|   - YooKassaPaymentsApi (2.20.1): |   - YooKassaPaymentsApi (2.21.3): | ||||||
|     - FunctionalSwift |     - FunctionalSwift | ||||||
|     - YooMoneyCoreApi (~> 2.1) |     - YooMoneyCoreApi (~> 3.0) | ||||||
|   - YooKassaWalletApi (2.3.2): |   - YooKassaWalletApi (2.3.2): | ||||||
|     - FunctionalSwift |     - FunctionalSwift | ||||||
|     - YooMoneyCoreApi |     - YooMoneyCoreApi | ||||||
|   - YooMoneyCoreApi (2.1.0): |   - YooMoneyCoreApi (3.0.7): | ||||||
|     - FunctionalSwift (~> 1.8.0) |     - FunctionalSwift (~> 2.0) | ||||||
|   - YooMoneySessionProfiler (5.0.1): |   - YooMoneySessionProfiler (5.0.1): | ||||||
|     - MobileSdk (~> 2.0) |     - MobileSdk (~> 2.0) | ||||||
|   - YooMoneyUI (6.2.0): |   - YooMoneyUI (7.3.2): | ||||||
|     - FunctionalSwift |     - FunctionalSwift | ||||||
| 
 | 
 | ||||||
| DEPENDENCIES: | DEPENDENCIES: | ||||||
| @ -52,6 +55,7 @@ SPEC REPOS: | |||||||
|     - YooMoneySessionProfiler |     - YooMoneySessionProfiler | ||||||
|     - YooMoneyUI |     - YooMoneyUI | ||||||
|   https://github.com/CocoaPods/Specs.git: |   https://github.com/CocoaPods/Specs.git: | ||||||
|  |     - SPaySDK | ||||||
|     - YandexMobileMetrica |     - YandexMobileMetrica | ||||||
| 
 | 
 | ||||||
| EXTERNAL SOURCES: | EXTERNAL SOURCES: | ||||||
| @ -62,18 +66,19 @@ EXTERNAL SOURCES: | |||||||
| 
 | 
 | ||||||
| SPEC CHECKSUMS: | SPEC CHECKSUMS: | ||||||
|   Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 |   Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 | ||||||
|   FunctionalSwift: b65b0a7ddde7f11a11e794f79a1e8009724ed0bd |   FunctionalSwift: f812f61d24f78fdac9fb361f26c7f21acc337c91 | ||||||
|   MobileSdk: 827ec8a9ef58a60f35e920cebaecf74f20a250c4 |   MobileSdk: 827ec8a9ef58a60f35e920cebaecf74f20a250c4 | ||||||
|   MoneyAuth: dedc9545fa857e7b489333e92403fe608585e518 |   MoneyAuth: 47daad5ba74241b1a8ebae3b0ea4eb6600867939 | ||||||
|  |   SPaySDK: 1015f868b6e9255457704cd6a3d051829263661a | ||||||
|   YandexMobileMetrica: f5368ee93f286c793d73b58da00929babfc897c1 |   YandexMobileMetrica: f5368ee93f286c793d73b58da00929babfc897c1 | ||||||
|   yookassa_payments_flutter: 9c4a1c019f2b042ebbd0b45fe19380054240d70a |   yookassa_payments_flutter: 7c9be9ba6fdae53b98b2e715a3d80d42e2bdd8ff | ||||||
|   YooKassaPayments: 09f7cb2b3562130aed01d75bba653a8f0d96d9f6 |   YooKassaPayments: 854eed87863761c6e9c164ece203f125e1bffb64 | ||||||
|   YooKassaPaymentsApi: d198a1da65988af52bd408d5d5d1c8cd93f039a2 |   YooKassaPaymentsApi: b6172fa43e58e79ad730c3ccc2692471cee6ea9c | ||||||
|   YooKassaWalletApi: cbb352525bfe89fd2ad52635062f79f8bbbc23ec |   YooKassaWalletApi: cbb352525bfe89fd2ad52635062f79f8bbbc23ec | ||||||
|   YooMoneyCoreApi: ddf9ea035b9a3f8d0563b4da8e55652fa07040d3 |   YooMoneyCoreApi: 0e5c123a9c981ea2384b86986d3ba64a096431f9 | ||||||
|   YooMoneySessionProfiler: 1a19bed99feca98c04e2a906908f91a7d5db408d |   YooMoneySessionProfiler: 1a19bed99feca98c04e2a906908f91a7d5db408d | ||||||
|   YooMoneyUI: 01f293ed3486e00c5244a5feded457e7cdc18074 |   YooMoneyUI: 94078f98dc65bee756c215a14fbf70ad3469f289 | ||||||
| 
 | 
 | ||||||
| PODFILE CHECKSUM: 6abfb72a0d401d5c53824cfe614a85f37a1a3040 | PODFILE CHECKSUM: 6abfb72a0d401d5c53824cfe614a85f37a1a3040 | ||||||
| 
 | 
 | ||||||
| COCOAPODS: 1.11.3 | COCOAPODS: 1.14.2 | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| 	archiveVersion = 1; | 	archiveVersion = 1; | ||||||
| 	classes = { | 	classes = { | ||||||
| 	}; | 	}; | ||||||
| 	objectVersion = 51; | 	objectVersion = 54; | ||||||
| 	objects = { | 	objects = { | ||||||
| 
 | 
 | ||||||
| /* Begin PBXBuildFile section */ | /* Begin PBXBuildFile section */ | ||||||
| @ -407,7 +407,7 @@ | |||||||
| 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | ||||||
| 				ENABLE_BITCODE = NO; | 				ENABLE_BITCODE = NO; | ||||||
| 				INFOPLIST_FILE = Runner/Info.plist; | 				INFOPLIST_FILE = Runner/Info.plist; | ||||||
| 				IPHONEOS_DEPLOYMENT_TARGET = 10.0; | 				IPHONEOS_DEPLOYMENT_TARGET = 13.0; | ||||||
| 				LD_RUNPATH_SEARCH_PATHS = ( | 				LD_RUNPATH_SEARCH_PATHS = ( | ||||||
| 					"$(inherited)", | 					"$(inherited)", | ||||||
| 					"@executable_path/Frameworks", | 					"@executable_path/Frameworks", | ||||||
| @ -431,7 +431,7 @@ | |||||||
| 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | ||||||
| 				ENABLE_BITCODE = NO; | 				ENABLE_BITCODE = NO; | ||||||
| 				INFOPLIST_FILE = Runner/Info.plist; | 				INFOPLIST_FILE = Runner/Info.plist; | ||||||
| 				IPHONEOS_DEPLOYMENT_TARGET = 10.0; | 				IPHONEOS_DEPLOYMENT_TARGET = 13.0; | ||||||
| 				LD_RUNPATH_SEARCH_PATHS = ( | 				LD_RUNPATH_SEARCH_PATHS = ( | ||||||
| 					"$(inherited)", | 					"$(inherited)", | ||||||
| 					"@executable_path/Frameworks", | 					"@executable_path/Frameworks", | ||||||
|  | |||||||
| @ -28,6 +28,11 @@ | |||||||
| 	<string>LaunchScreen</string> | 	<string>LaunchScreen</string> | ||||||
| 	<key>UIMainStoryboardFile</key> | 	<key>UIMainStoryboardFile</key> | ||||||
| 	<string>Main</string> | 	<string>Main</string> | ||||||
|  |     <key>LSApplicationQueriesSchemes</key> | ||||||
|  |     <array> | ||||||
|  |         <string>yoomoneyauth</string> | ||||||
|  |         <string>sberpay</string> | ||||||
|  |     </array> | ||||||
| 	<key>UISupportedInterfaceOrientations</key> | 	<key>UISupportedInterfaceOrientations</key> | ||||||
| 	<array> | 	<array> | ||||||
| 		<string>UIInterfaceOrientationPortrait</string> | 		<string>UIInterfaceOrientationPortrait</string> | ||||||
|  | |||||||
| @ -55,9 +55,14 @@ class _SuccessTokenizationScreenState extends State<SuccessTokenizationScreen> { | |||||||
|           ), |           ), | ||||||
|           ElevatedButton( |           ElevatedButton( | ||||||
|               onPressed: () async { |               onPressed: () async { | ||||||
|  |                 var shopId = "<Идентификатор магазина в ЮKassa>"; | ||||||
|                 var clientApplicationKey = "<Ключ для клиентских приложений>"; |                 var clientApplicationKey = "<Ключ для клиентских приложений>"; | ||||||
|                 await YookassaPaymentsFlutter.confirmation( |                 await YookassaPaymentsFlutter.confirmation( | ||||||
|                     controller.text, result.paymentMethodType, clientApplicationKey); |                     controller.text, | ||||||
|  |                     result.paymentMethodType, | ||||||
|  |                     clientApplicationKey, | ||||||
|  |                     shopId | ||||||
|  |                 ); | ||||||
|                 showDialog( |                 showDialog( | ||||||
|                     context: context, |                     context: context, | ||||||
|                     builder: (context) => const AlertDialog( |                     builder: (context) => const AlertDialog( | ||||||
|  | |||||||
| @ -45,8 +45,7 @@ class TokenizationScreenState extends State<TokenizationScreen> { | |||||||
| 
 | 
 | ||||||
|   void startTokenization() async { |   void startTokenization() async { | ||||||
|     var clientApplicationKey = "<Ключ для клиентских приложений>"; |     var clientApplicationKey = "<Ключ для клиентских приложений>"; | ||||||
|     var amount = |     var amount = Amount(value: controller.text, currency: Currency.rub); | ||||||
|         Amount(value: double.parse(controller.text), currency: Currency.rub); |  | ||||||
|     var moneyAuthClientId = "<ID для центра авторизации в системе YooMoney>"; |     var moneyAuthClientId = "<ID для центра авторизации в системе YooMoney>"; | ||||||
|     var shopId = "<Идентификатор магазина в ЮKassa>"; |     var shopId = "<Идентификатор магазина в ЮKassa>"; | ||||||
|     var applicationScheme = "<Схема вашего приложения для deeplink>" "://"; |     var applicationScheme = "<Схема вашего приложения для deeplink>" "://"; | ||||||
|  | |||||||
| @ -5,58 +5,58 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: async |       name: async | ||||||
|       url: "https://pub.dartlang.org" |       sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.8.2" |     version: "2.11.0" | ||||||
|   boolean_selector: |   boolean_selector: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: boolean_selector |       name: boolean_selector | ||||||
|       url: "https://pub.dartlang.org" |       sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.1.0" |     version: "2.1.1" | ||||||
|   characters: |   characters: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: characters |       name: characters | ||||||
|       url: "https://pub.dartlang.org" |       sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.2.0" |     version: "1.3.0" | ||||||
|   charcode: |  | ||||||
|     dependency: transitive |  | ||||||
|     description: |  | ||||||
|       name: charcode |  | ||||||
|       url: "https://pub.dartlang.org" |  | ||||||
|     source: hosted |  | ||||||
|     version: "1.3.1" |  | ||||||
|   clock: |   clock: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: clock |       name: clock | ||||||
|       url: "https://pub.dartlang.org" |       sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.1.0" |     version: "1.1.1" | ||||||
|   collection: |   collection: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: collection |       name: collection | ||||||
|       url: "https://pub.dartlang.org" |       sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.15.0" |     version: "1.18.0" | ||||||
|   cupertino_icons: |   cupertino_icons: | ||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       name: cupertino_icons |       name: cupertino_icons | ||||||
|       url: "https://pub.dartlang.org" |       sha256: "1989d917fbe8e6b39806207df5a3fdd3d816cbd090fac2ce26fb45e9a71476e5" | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.0.4" |     version: "1.0.4" | ||||||
|   fake_async: |   fake_async: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: fake_async |       name: fake_async | ||||||
|       url: "https://pub.dartlang.org" |       sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.2.0" |     version: "1.3.1" | ||||||
|   flutter: |   flutter: | ||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: flutter |     description: flutter | ||||||
| @ -66,7 +66,8 @@ packages: | |||||||
|     dependency: "direct dev" |     dependency: "direct dev" | ||||||
|     description: |     description: | ||||||
|       name: flutter_lints |       name: flutter_lints | ||||||
|       url: "https://pub.dartlang.org" |       sha256: b543301ad291598523947dc534aaddc5aaad597b709d2426d3a0e0d44c5cb493 | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.0.4" |     version: "1.0.4" | ||||||
|   flutter_test: |   flutter_test: | ||||||
| @ -78,37 +79,42 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: lints |       name: lints | ||||||
|       url: "https://pub.dartlang.org" |       sha256: a2c3d198cb5ea2e179926622d433331d8b58374ab8f29cdda6e863bd62fd369c | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.0.1" |     version: "1.0.1" | ||||||
|   matcher: |   matcher: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: matcher |       name: matcher | ||||||
|       url: "https://pub.dartlang.org" |       sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "0.12.11" |     version: "0.12.16" | ||||||
|   material_color_utilities: |   material_color_utilities: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: material_color_utilities |       name: material_color_utilities | ||||||
|       url: "https://pub.dartlang.org" |       sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "0.1.3" |     version: "0.5.0" | ||||||
|   meta: |   meta: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: meta |       name: meta | ||||||
|       url: "https://pub.dartlang.org" |       sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.7.0" |     version: "1.10.0" | ||||||
|   path: |   path: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: path |       name: path | ||||||
|       url: "https://pub.dartlang.org" |       sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.8.0" |     version: "1.8.3" | ||||||
|   sky_engine: |   sky_engine: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: flutter |     description: flutter | ||||||
| @ -118,65 +124,73 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: source_span |       name: source_span | ||||||
|       url: "https://pub.dartlang.org" |       sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.8.1" |     version: "1.10.0" | ||||||
|   stack_trace: |   stack_trace: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: stack_trace |       name: stack_trace | ||||||
|       url: "https://pub.dartlang.org" |       sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.10.0" |     version: "1.11.1" | ||||||
|   stream_channel: |   stream_channel: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: stream_channel |       name: stream_channel | ||||||
|       url: "https://pub.dartlang.org" |       sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.1.0" |     version: "2.1.2" | ||||||
|   string_scanner: |   string_scanner: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: string_scanner |       name: string_scanner | ||||||
|       url: "https://pub.dartlang.org" |       sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.1.0" |     version: "1.2.0" | ||||||
|   term_glyph: |   term_glyph: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: term_glyph |       name: term_glyph | ||||||
|       url: "https://pub.dartlang.org" |       sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.2.0" |     version: "1.2.1" | ||||||
|   test_api: |   test_api: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: test_api |       name: test_api | ||||||
|       url: "https://pub.dartlang.org" |       sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "0.4.8" |     version: "0.6.1" | ||||||
|   typed_data: |  | ||||||
|     dependency: transitive |  | ||||||
|     description: |  | ||||||
|       name: typed_data |  | ||||||
|       url: "https://pub.dartlang.org" |  | ||||||
|     source: hosted |  | ||||||
|     version: "1.3.0" |  | ||||||
|   vector_math: |   vector_math: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: vector_math |       name: vector_math | ||||||
|       url: "https://pub.dartlang.org" |       sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" | ||||||
|  |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.1.1" |     version: "2.1.4" | ||||||
|  |   web: | ||||||
|  |     dependency: transitive | ||||||
|  |     description: | ||||||
|  |       name: web | ||||||
|  |       sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 | ||||||
|  |       url: "https://pub.dev" | ||||||
|  |     source: hosted | ||||||
|  |     version: "0.3.0" | ||||||
|   yookassa_payments_flutter: |   yookassa_payments_flutter: | ||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       path: ".." |       path: ".." | ||||||
|       relative: true |       relative: true | ||||||
|     source: path |     source: path | ||||||
|     version: "1.0.5" |     version: "1.2.2" | ||||||
| sdks: | sdks: | ||||||
|   dart: ">=2.15.0 <3.0.0" |   dart: ">=3.2.0-194.0.dev <4.0.0" | ||||||
|   flutter: ">=2.10.5" |   flutter: ">=2.10.5" | ||||||
|  | |||||||
| @ -201,6 +201,7 @@ extension TokenizationModuleInputData: Decodable { | |||||||
|     enum CodingKeys: String, CodingKey { |     enum CodingKeys: String, CodingKey { | ||||||
|         case clientApplicationKey = "clientApplicationKey" |         case clientApplicationKey = "clientApplicationKey" | ||||||
|         case shopName = "title" |         case shopName = "title" | ||||||
|  |         case shopId = "shopId" | ||||||
|         case purchaseDescription = "subtitle" |         case purchaseDescription = "subtitle" | ||||||
|         case amount = "amount" |         case amount = "amount" | ||||||
|         case savePaymentMethod = "savePaymentMethod" |         case savePaymentMethod = "savePaymentMethod" | ||||||
| @ -223,6 +224,7 @@ extension TokenizationModuleInputData: Decodable { | |||||||
| 
 | 
 | ||||||
|         let clientApplicationKey = try values.decode(String.self, forKey: .clientApplicationKey) |         let clientApplicationKey = try values.decode(String.self, forKey: .clientApplicationKey) | ||||||
|         let shopName = try values.decode(String.self, forKey: .shopName) |         let shopName = try values.decode(String.self, forKey: .shopName) | ||||||
|  |         let shopId = try values.decode(String.self, forKey: .shopId) | ||||||
|         let purchaseDescription = try values.decode(String.self, forKey: .purchaseDescription) |         let purchaseDescription = try values.decode(String.self, forKey: .purchaseDescription) | ||||||
|         let amount = try values.decode(Amount.self, forKey: .amount) |         let amount = try values.decode(Amount.self, forKey: .amount) | ||||||
|         let gatewayId = try? values.decode(String.self, forKey: .gatewayId) |         let gatewayId = try? values.decode(String.self, forKey: .gatewayId) | ||||||
| @ -258,6 +260,7 @@ extension TokenizationModuleInputData: Decodable { | |||||||
|         self.init( |         self.init( | ||||||
|             clientApplicationKey: clientApplicationKey, |             clientApplicationKey: clientApplicationKey, | ||||||
|             shopName: shopName, |             shopName: shopName, | ||||||
|  |             shopId: shopId, | ||||||
|             purchaseDescription: purchaseDescription, |             purchaseDescription: purchaseDescription, | ||||||
|             amount: amount, |             amount: amount, | ||||||
|             gatewayId: gatewayId, |             gatewayId: gatewayId, | ||||||
| @ -343,9 +346,10 @@ extension Amount: Decodable { | |||||||
|     public init(from decoder: Decoder) throws { |     public init(from decoder: Decoder) throws { | ||||||
|         let values = try decoder.container(keyedBy: CodingKeys.self) |         let values = try decoder.container(keyedBy: CodingKeys.self) | ||||||
| 
 | 
 | ||||||
|         let value = try values.decode(Double.self, forKey: .value) |         let stringValue = try values.decode(String.self, forKey: .value) | ||||||
|  |         guard let decimalValue = Decimal(string: stringValue) else { throw CommonError.decodingError } | ||||||
|         let currency = try values.decode(String.self, forKey: .currency) |         let currency = try values.decode(String.self, forKey: .currency) | ||||||
|         self.init(value: Decimal(value), currency: .custom(currency)) |         self.init(value: decimalValue, currency: .custom(currency)) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -428,6 +432,10 @@ extension CustomizationSettings: Decodable { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | public enum CommonError: Error { | ||||||
|  |     case decodingError | ||||||
|  | } | ||||||
|  | 
 | ||||||
| struct Color: Decodable { | struct Color: Decodable { | ||||||
| 
 | 
 | ||||||
|     let red: CGFloat |     let red: CGFloat | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ Flutter SDK from yoomoney | |||||||
|   s.source           = { :path => '.' } |   s.source           = { :path => '.' } | ||||||
|   s.source_files = 'Classes/**/*' |   s.source_files = 'Classes/**/*' | ||||||
|   s.dependency 'Flutter' |   s.dependency 'Flutter' | ||||||
|   s.dependency 'YooKassaPayments', '6.12.3' |   s.dependency 'YooKassaPayments', '6.14.0' | ||||||
| 
 | 
 | ||||||
|   s.platform = :ios, '10.0' |   s.platform = :ios, '10.0' | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -20,7 +20,6 @@ class SavedBankCardModuleInputData { | |||||||
|   String? customerId; |   String? customerId; | ||||||
|   bool isSafeDeal; |   bool isSafeDeal; | ||||||
|   HostParameters? hostParameters; |   HostParameters? hostParameters; | ||||||
|   String? applePayID; |  | ||||||
| 
 | 
 | ||||||
|   SavedBankCardModuleInputData( |   SavedBankCardModuleInputData( | ||||||
|       {required this.clientApplicationKey, |       {required this.clientApplicationKey, | ||||||
| @ -37,8 +36,7 @@ class SavedBankCardModuleInputData { | |||||||
|       this.isLoggingEnabled = false, |       this.isLoggingEnabled = false, | ||||||
|       this.customizationSettings = const CustomizationSettings(), |       this.customizationSettings = const CustomizationSettings(), | ||||||
|       this.customerId, |       this.customerId, | ||||||
|       this.hostParameters, |       this.hostParameters}); | ||||||
|       this.applePayID}); |  | ||||||
| 
 | 
 | ||||||
|   Map<String, dynamic> toJson() => { |   Map<String, dynamic> toJson() => { | ||||||
|         'clientApplicationKey': clientApplicationKey, |         'clientApplicationKey': clientApplicationKey, | ||||||
| @ -48,7 +46,6 @@ class SavedBankCardModuleInputData { | |||||||
|         'savePaymentMethod': savePaymentMethod.toString(), |         'savePaymentMethod': savePaymentMethod.toString(), | ||||||
|         'gatewayId': gatewayId, |         'gatewayId': gatewayId, | ||||||
|         'testModeSettings': testModeSettings?.toJson(), |         'testModeSettings': testModeSettings?.toJson(), | ||||||
|         'applePayMerchantIdentifier': applePayID, |  | ||||||
|         'shopId': shopId, |         'shopId': shopId, | ||||||
|         'returnUrl': returnUrl, |         'returnUrl': returnUrl, | ||||||
|         'isLoggingEnabled': isLoggingEnabled, |         'isLoggingEnabled': isLoggingEnabled, | ||||||
|  | |||||||
| @ -26,7 +26,6 @@ class TokenizationModuleInputData { | |||||||
|   String? customerId; |   String? customerId; | ||||||
|   GooglePayParameters googlePayParameters; |   GooglePayParameters googlePayParameters; | ||||||
|   bool googlePayTestEnvironment; |   bool googlePayTestEnvironment; | ||||||
|   String? applePayID; |  | ||||||
| 
 | 
 | ||||||
|   TokenizationModuleInputData( |   TokenizationModuleInputData( | ||||||
|       {required this.clientApplicationKey, |       {required this.clientApplicationKey, | ||||||
| @ -47,8 +46,7 @@ class TokenizationModuleInputData { | |||||||
|       this.applicationScheme, |       this.applicationScheme, | ||||||
|       this.customerId, |       this.customerId, | ||||||
|       this.googlePayParameters = const GooglePayParameters(), |       this.googlePayParameters = const GooglePayParameters(), | ||||||
|       this.googlePayTestEnvironment = false, |       this.googlePayTestEnvironment = false}); | ||||||
|       this.applePayID}); |  | ||||||
| 
 | 
 | ||||||
|   Map<String, dynamic> toJson() => { |   Map<String, dynamic> toJson() => { | ||||||
|         'clientApplicationKey': clientApplicationKey, |         'clientApplicationKey': clientApplicationKey, | ||||||
| @ -60,7 +58,6 @@ class TokenizationModuleInputData { | |||||||
|         'gatewayId': gatewayId, |         'gatewayId': gatewayId, | ||||||
|         'tokenizationSettings': tokenizationSettings.toJson(), |         'tokenizationSettings': tokenizationSettings.toJson(), | ||||||
|         'testModeSettings': testModeSettings?.toJson(), |         'testModeSettings': testModeSettings?.toJson(), | ||||||
|         'applePayMerchantIdentifier': applePayID, |  | ||||||
|         'shopId': shopId, |         'shopId': shopId, | ||||||
|         'returnUrl': returnUrl, |         'returnUrl': returnUrl, | ||||||
|         'isLoggingEnabled': isLoggingEnabled, |         'isLoggingEnabled': isLoggingEnabled, | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import 'currency.dart'; | import 'currency.dart'; | ||||||
| 
 | 
 | ||||||
| class Amount { | class Amount { | ||||||
|   double value; |   String value; | ||||||
|   Currency currency; |   Currency currency; | ||||||
| 
 | 
 | ||||||
|   Amount({required this.value, required this.currency}); |   Amount({required this.value, required this.currency}); | ||||||
|  | |||||||
| @ -12,18 +12,12 @@ class PaymentMethodTypes { | |||||||
|       PaymentMethodTypes([PaymentMethod.yooMoney]); |       PaymentMethodTypes([PaymentMethod.yooMoney]); | ||||||
|   static const PaymentMethodTypes sberbank = |   static const PaymentMethodTypes sberbank = | ||||||
|       PaymentMethodTypes([PaymentMethod.sberbank]); |       PaymentMethodTypes([PaymentMethod.sberbank]); | ||||||
|   static const PaymentMethodTypes applePay = |  | ||||||
|       PaymentMethodTypes([PaymentMethod.applePay]); |  | ||||||
|   static const PaymentMethodTypes googlePay = |  | ||||||
|       PaymentMethodTypes([PaymentMethod.googlePay]); |  | ||||||
|   static const PaymentMethodTypes sbp = |   static const PaymentMethodTypes sbp = | ||||||
|       PaymentMethodTypes([PaymentMethod.sbp]); |       PaymentMethodTypes([PaymentMethod.sbp]); | ||||||
|   static const PaymentMethodTypes all = PaymentMethodTypes([ |   static const PaymentMethodTypes all = PaymentMethodTypes([ | ||||||
|     PaymentMethod.bankCard, |     PaymentMethod.bankCard, | ||||||
|     PaymentMethod.yooMoney, |     PaymentMethod.yooMoney, | ||||||
|     PaymentMethod.sberbank, |     PaymentMethod.sberbank, | ||||||
|     PaymentMethod.applePay, |  | ||||||
|     PaymentMethod.googlePay, |  | ||||||
|     PaymentMethod.sbp |     PaymentMethod.sbp | ||||||
|   ]); |   ]); | ||||||
| } | } | ||||||
| @ -39,10 +33,6 @@ extension PaymentMethodExtension on PaymentMethod { | |||||||
|         return PaymentMethod.yooMoney; |         return PaymentMethod.yooMoney; | ||||||
|       case 'sberbank': |       case 'sberbank': | ||||||
|         return PaymentMethod.sberbank; |         return PaymentMethod.sberbank; | ||||||
|       case 'apple_pay': |  | ||||||
|         return PaymentMethod.applePay; |  | ||||||
|       case 'google_pay': |  | ||||||
|         return PaymentMethod.googlePay; |  | ||||||
|       case 'sbp': |       case 'sbp': | ||||||
|         return PaymentMethod.sbp; |         return PaymentMethod.sbp; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -29,9 +29,14 @@ class YookassaPaymentsFlutter { | |||||||
|         .then((value) => TokenizationResult.fromJson(json.decode(value))); |         .then((value) => TokenizationResult.fromJson(json.decode(value))); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   static Future<void> confirmation( |   static Future<void> confirmation(String url, PaymentMethod? paymentMethod, | ||||||
|       String url, PaymentMethod? paymentMethod, String? clientApplicationKey) async { |       String? clientApplicationKey, String? shopId) async { | ||||||
|     var inputData = {'url': url, 'paymentMethod': paymentMethod?.name, 'clientApplicationKey': clientApplicationKey}; |     var inputData = { | ||||||
|  |       'url': url, | ||||||
|  |       'paymentMethod': paymentMethod?.name, | ||||||
|  |       'clientApplicationKey': clientApplicationKey, | ||||||
|  |       'shopId': shopId | ||||||
|  |     }; | ||||||
|     return await _channel.invokeMethod('confirmation', inputData); |     return await _channel.invokeMethod('confirmation', inputData); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| name: yookassa_payments_flutter | name: yookassa_payments_flutter | ||||||
| description: This Flutter SDK allows processing payments using a payment token. It | description: This Flutter SDK allows processing payments using a payment token. It | ||||||
|   works as an addition to the YooMoney API. |   works as an addition to the YooMoney API. | ||||||
| version: 1.2.2 | version: 1.3.0 | ||||||
| homepage: https://git.yoomoney.ru/projects/SDK/repos/yookassa-payments-flutter-sdk/browse | homepage: https://git.yoomoney.ru/projects/SDK/repos/yookassa-payments-flutter-sdk/browse | ||||||
| repository: https://git.yoomoney.ru/projects/SDK/repos/yookassa-payments-flutter-sdk/browse | repository: https://git.yoomoney.ru/projects/SDK/repos/yookassa-payments-flutter-sdk/browse | ||||||
| environment: | environment: | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user