Если ваше приложение Android распространяется через Google Play, вы можете интегрировать его с Google Pay API и настроить в нем поддержку платежных карт. О том, как это сделать, рассказывается ниже.
- Шаг 1. Укажите версию Google Pay API
- Шаг 2. Запросите токен для поставщика платежных услуг
- Шаг 3. Задайте поддерживаемые платежные системы
- Шаг 4. Укажите поддерживаемые способы оплаты
- Шаг 5. Создайте экземпляр объекта PaymentsClient
- Шаг 6. Определите готовность к оплате с помощью Google Pay API
- Шаг 7. Создайте объект PaymentDataRequest
- Шаг 8. Настройте обработчик жестов пользователей
- Шаг 9. Обработайте объект ответа
- Выводы
Шаг 1. Укажите версию Google Pay API
Укажите версию Google Pay API, которая используется в вашем приложении. Основной и дополнительный номера версии указываются в ответе и влияют на то, какой набор полей будет проверяться во всех объектах.
Создайте базовый объект запроса со свойствами, имеющимися во всех прочих объектах запроса.
Kotlin
private val baseRequest = JSONObject().apply { put("apiVersion", 2) put("apiVersionMinor", 0) }
Java
private static JSONObject getBaseRequest() throws JSONException { return new JSONObject().put("apiVersion", 2).put("apiVersionMinor", 0); }
Шаг 2. Запросите токен для поставщика платежных услуг
Компания Google шифрует информацию о выбранной карте покупателя, чтобы обеспечить безопасную обработку данных поставщиком платежных услуг.
Kotlin
private fun gatewayTokenizationSpecification(): JSONObject { return JSONObject().apply { put("type", "PAYMENT_GATEWAY") put("parameters", JSONObject(mapOf( "gateway" to "example", "gatewayMerchantId" to "exampleGatewayMerchantId"))) } }
Java
private static JSONObject getGatewayTokenizationSpecification() throws JSONException { return new JSONObject() {{ put("type", "PAYMENT_GATEWAY"); put("parameters", new JSONObject() {{ put("gateway", "example"); put("gatewayMerchantId", "exampleGatewayMerchantId"); }}); }}; }
Замените значения example и exampleGatewayMerchantId значениями, подходящими для вашего поставщика платежных услуг. В таблице ниже приведены значения gateway
и gatewayMerchantId
для конкретных поставщиков.
Шлюз | Значения параметров и ссылки на документацию |
---|---|
ABA PayWay |
"gateway": "ababank" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
accept.blue |
"gateway": "acceptblue" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
ACI |
"gateway": "aciworldwide" "gatewayMerchantId": "YOUR_ENTITY_ID" |
ACpay |
"gateway": "acpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Acquired.com |
"gateway": "acquired" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Adyen |
"gateway": "adyen" "gatewayMerchantId": "YOUR_MERCHANT_ACCOUNT_NAME" |
Airba Pay |
"gateway": "airbapay" "gatewayMerchantId": "YOUR_MERCHANT_ACCOUNT_NAME" |
Airvend |
"gateway": "airvend" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Airwallex |
"gateway": "airwallex" "gatewayMerchantId": "YOUR_MERCHANT_ACCOUNT_NAME" |
Akurateco |
"gateway": "akuratecolab" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Альфа-Банк |
"gateway": "alfabank" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Algoritma |
"gateway": "algoritma" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Allinpay |
"gateway": "allinpayintl" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
AllPayments |
"gateway": "allpayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
alticepay |
"gateway": "alticepay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Anedot |
"gateway": "anedot" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
ApcoPay |
"gateway": "apcopay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
АППЕКС |
"gateway": "epos" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
AsiaBill |
"gateway": "asiabill" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" Документация для разработчиков отсутствует |
Assist |
"gateway": "assist" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Assist Belarus |
"gateway": "belassist" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Assist Kazakhstan |
"gateway": "assistkz" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Aurus |
"gateway": "auruspay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Axerve |
"gateway": "gestpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Bank 131 |
"gateway": "bank131" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Bank Vostok |
"gateway": "bankvostok" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Barclaycard |
"gateway": "barclayssmartpayadvance" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Barion |
"gateway": "barion" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
BCC.KZ |
"gateway": "bccpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
bePaid |
"gateway": "ecomcharge" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Bereke Bank |
"gateway": "berekepay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Платежные системы |
"gateway": "billingsystems" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Bizzon |
"gateway": "bizzon" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Blocks |
"gateway": "blocks" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Bluefin |
"gateway": "bluefin" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Blue Media |
"gateway": "bluemedia" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
BlueSnap |
"gateway": "bluesnap" "gatewayMerchantId": "YOUR_shopToken" |
BPC |
"gateway": "bpcpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
BR-DGE |
"gateway": "comcarde" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Braintree |
"gateway": "braintree" "braintree:apiVersion": "v1" "braintree:sdkVersion": "braintree.client.VERSION" "braintree:merchantId": "YOUR_BRAINTREE_MERCHANT_ID" "braintree:clientKey": "YOUR_BRAINTREE_TOKENIZATION_KEY" |
Braspag |
"gateway": "cielo" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
BridgerPay |
"gateway": "bridgerpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Buya |
"gateway": "buya" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
CardCom |
"gateway": "cardcom" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
CardConnect |
"gateway": "cardconnect" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Cardknox |
"gateway": "cardknox" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Cardstream |
"gateway": "crst" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Cashflows |
"gateway": "cashflowsgateway" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Cathay United Bank |
"gateway": "cathaybk" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
CCavenue UAE |
"gateway": "ccavenueuae" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Cecabank |
"gateway": "cecabank" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Celerispay |
"gateway": "celerispay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
CentralPay |
"gateway": "centralpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Chargehive |
"gateway": "chargehive" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
CharityEngine |
"gateway": "charityengine" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Merchant Services (Chase) |
"gateway": "chase" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Checkout.com |
"gateway": "checkoutltd" "gatewayMerchantId": "YOUR_PUBLIC_KEY" |
CityPay |
"gateway": "citypay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Cloud9 Payment Gateway (C9PG) |
"gateway": "c9pg" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
CloudPayments |
"gateway": "cloudpayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
CloudWalk |
"gateway": "cloudwalk" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Computop |
"gateway": "computop" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
ConcordPay |
"gateway": "concordpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Connectum |
"gateway": "connectum" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
ConnexPay |
"gateway": "connexpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Corefy |
"gateway": "paycoreio" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Corvus Pay |
"gateway": "corvuspay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Credorax |
"gateway": "credorax" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
CrossPay |
"gateway": "crosspay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
CSG Forte |
"gateway": "csgforte" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
CTBC Bank |
"gateway": "ctbcbank" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
CURO Payments |
"gateway": "curopayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
CyberSource |
"gateway": "cybersource" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
danube.pay |
"gateway": "danubepay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Datacap Systems, Inc. |
"gateway": "datacap systems inc." "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Datatrans |
"gateway": "datatrans" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
DECTA |
"gateway": "decta" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" Документация для разработчиков отсутствует |
Deutsche Bank AG |
"gateway": "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" окументация для разработчиков отсутствует |
Deutsche Bank – Merchant Solutions |
"gateway": "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
DG Financial Technology, Inc. |
"gateway": "veritrans" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Digital Finance |
"gateway": "digitalfinance" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
dLocal |
"gateway": "dlocal" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
DNA Payments |
"gateway": "dnapayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Dojo |
"gateway": "dojo" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Dotpay |
"gateway": "dotpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
e-SiTef – Software Express |
"gateway": "softwareexpress" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
easycard |
"gateway": "easycard" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
EasyPay |
"gateway": "easypay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
EBANX |
"gateway": "ebanx" "gatewayMerchantId": "YOUR_PUBLIC_INTEGRATION_KEY" |
eCard |
"gateway": "ecard" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
ECOMMPAY |
"gateway": "ecommpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Ecopaynet |
"gateway": "ecopaynet" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
ECPay |
"gateway": "ecpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" Документация для разработчиков отсутствует |
eGHL |
"gateway": "eghl" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Elavon (Converge) |
"gateway": "convergepay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Emerchantpay |
"gateway": "emerchantpay" "gatewayMerchantID": "YOUR_GATEWAY_MERCHANT_ID" |
emspay |
"gateway": "emsonline" "gatewayMerchantID": "YOUR_GATEWAY_MERCHANT_ID" |
Encoded |
"gateway": "encoded" "gatewayMerchantID": "YOUR_GATEWAY_MERCHANT_ID" |
EpicPay |
"gateway": "epicpay" "gatewayMerchantID": "YOUR_GATEWAY_MERCHANT_ID" |
Espago |
"gateway": "espago" "gatewayMerchantID": "YOUR_GATEWAY_MERCHANT_ID" |
EveryPay |
"gateway": "everypay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
EVONET |
"gateway": "cardinfolink" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
EvoPay |
"gateway": "evopay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Evo Payment Gateway |
"gateway": "evopaymentgateway" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" Документация для разработчиков отсутствует |
exactly.com |
"gateway": "exactly" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Exact Payments |
"gateway": "exactpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Fat Zebra |
"gateway": "fatzebra" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Fenige |
"gateway": "fenige" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Fibonatix |
"gateway": "fibonatixparagon" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Financial Line |
"gateway": "finline" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Finanso UA |
"gateway": "finansoua" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
FINEXUS |
"gateway": "finexus" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Finix |
"gateway": "finix" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
First American by Deluxe |
"gateway": "firstpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
First Data (Payeezy) |
"gateway": "firstdata" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
FIS Biller Solutions |
"gateway": "fisglobalbsp" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Fluid Pay |
"gateway": "fluidpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
FM Finance LTD |
"gateway": "fmfinanceltd" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
ForteBank |
"gateway": "fortebank" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Банк "Фридом Финанс" |
"gateway": "axayscom" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
FreedomPay |
"gateway": "freedompay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
FreedomPay.Money |
"gateway": "payboxmoney" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Freepay |
"gateway": "freepay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Frontstream |
"gateway": "frontstreampayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Fung Payments |
"gateway": "fungpayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
GBPayments |
"gateway": "gbpayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
geidea |
"gateway": "geidea" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
GETTRX |
"gateway": "globalelectronictechnology" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Global One Pay |
"gateway": "globalonepay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" Документация для разработчиков отсутствует |
Global Payments |
"gateway": "globalpayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
GMO Payment Gateway |
"gateway": "gmopg" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
GoDaddy Payments |
"gateway": "godaddypayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Good Idea Technologies |
"gateway": "git" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
GoPay |
"gateway": "gopay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
GP Webpay |
"gateway": "gpwebpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" Документация для разработчиков отсутствует |
Gr4vy |
"gateway": "gr4vy" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Gravity Payments |
"gateway": "gravitypayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Halyk Bank |
"gateway": "halykbank" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Helcim |
"gateway": "helcim" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
HIPS |
"gateway": "hips" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
HiTrust |
"gateway": "hitrustpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Hyp |
"gateway": "hyp" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
icard |
"gateway": "icardwallet" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
iKhokha |
"gateway": "ikhokha" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
imoje |
"gateway": "imoje" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Impaya |
"gateway": "impayarus" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
ИнПлат |
"gateway": "inplat" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
InstaMed |
"gateway": "instamed" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
IntellectMoney |
"gateway": "intellectmoney" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Interactive Transaction Solutions |
"gateway": "interactivets" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Interswitch Payment Gateway |
"gateway": "interswitch" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Intervale |
"gateway": "intervale" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
ioka fintech |
"gateway": "ioka" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
iPay88 |
"gateway": "ipay88" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
IPSI |
"gateway": "ipsi" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
iQmetrix |
"gateway": "iqmetrixpaymentservicesgateway" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
IXOPAY |
"gateway": "ixopay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
JetPay |
"gateway": "jetpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
JudoPay |
"gateway": "judopay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" Документация для разработчиков отсутствует |
Kassa |
"gateway": "kassacom" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
kassa24pay |
"gateway": "kassa24pay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Kineox |
"gateway": "kineox" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Klix by Citadele |
"gateway": "klix" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
LHV Pank |
"gateway": "lhvpank" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Liberty |
"gateway": "liberty" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Life Pay |
"gateway": "lifepay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Limepay |
"gateway": "limepay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
LiqPay |
"gateway": "liqpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Littlepay |
"gateway": "littlepay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
LogPay |
"gateway": "logpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Loyale |
"gateway": "loyale" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
lynck |
"gateway": "lynck" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Lyra |
"gateway": "lyra" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Magnetiq Bank |
"gateway": "magnetiq" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
maib |
"gateway": "maibecomm" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
MakeCommerce (Maksekeskus) |
"gateway": "maksekeskus" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Mandarin |
"gateway": "mandarin" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Market Pay |
"gateway": "marketpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Mastercard Payment Gateway Services |
"gateway": "mpgs" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
MerchantE |
"gateway": "merchante" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Merchant Warrior |
"gateway": "merchantwarrior" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Minsait Payments Systems |
"gateway": "minsaitpaymentsgateway" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
MITEC |
"gateway": "mitecmx" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
MIXPLAT |
"gateway": "mixplat" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
МОБИ.Деньги |
"gateway": "mobimoney" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
МодульБанк |
"gateway": "modulbank" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Molpay |
"gateway": "molpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" Документация для разработчиков отсутствует |
Mondido |
"gateway": "mondido" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Monei |
"gateway": "monei" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
monek |
"gateway": "monek" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Moneris |
"gateway": "moneris" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Moneta |
"gateway": "moneta" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" Документация для разработчиков отсутствует |
Monext |
"gateway": "monext" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Деньги@Mail.Ru |
"gateway": "moneymailru" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
MPay |
"gateway": "managepay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
mstartipg |
"gateway": "mstartipg" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
МультиКарта |
"gateway": "mulitcarta" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
MultiSafepay |
"gateway": "multisafepay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Mundipagg |
"gateway": "mundipagg" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
MyCheck |
"gateway": "mycheck" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
MyChoice2Pay |
"gateway": "mychoice2pay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
MyFatoorah |
"gateway": "myfatoorah" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
MyPay |
"gateway": "mypay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" Документация для разработчиков отсутствует |
myPOS |
"gateway": "mypos" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
N&TS Group |
"gateway": "netsgroup" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
NCCC |
"gateway": "nccc" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Neon Pay |
"gateway": "neonpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Netopia |
"gateway": "netopia" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Netvalve |
"gateway": "netvalve" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
NewebPay (ранее STPath, Pay2Go) |
"gateway": "newebpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Newtech |
"gateway": "newtechmobile" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Nexi |
"gateway": "nexi" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
NMI |
"gateway": "gatewayservices" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
noon payments |
"gateway": "noonpayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Novalnet |
"gateway": "novalnet" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
NTT DATA |
"gateway": "nttdatahk" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Nuvei |
"gateway": "nuvei" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Oceanpayment |
"gateway": "oceanpayment" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Omise |
"gateway": "omise" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
One Inc |
"gateway": "oneinc" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Онэлия |
"gateway": "onelya" "gatewayMerchantId": "YOUR_GATWAY_MERCHANT_ID" |
Onerway |
"gateway": "ronghan" "gatewayMerchantId": "YOUR_GATWAY_MERCHANT_ID" |
OneVision Limited |
"gateway": "onevision" "gatewayMerchantId": "YOUR_GATWAY_MERCHANT_ID" |
OnPay |
"gateway": "onpayio" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Opayo by Elavon |
"gateway": "opayoelavon" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Oschadbank |
"gateway": "oschadbank" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
pagarme |
"gateway": "pagarme" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PagBank |
"gateway": "pagbank" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PagBrasil |
"gateway": "pagbrasil" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PagSeguro |
"gateway": "pagsegurointernational" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PAY2M |
"gateway": "pay2m" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Payarc |
"gateway": "payarc" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Pay.com |
"gateway": "paycom" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PAYCOMET |
"gateway": "paycomet" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Paydock |
"gateway": "paydock" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayEase |
"gateway": "payeasenet" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayEngine |
"gateway": "payengine" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayFabric |
"gateway": "payfabric" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayFacto |
"gateway": "payfacto" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
paygent |
"gateway": "paygent" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Payhub |
"gateway": "payhub" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayLane |
"gateway": "paylane" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Payler |
"gateway": "payler" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayLink® |
"gateway": "paylink" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Payload |
"gateway": "payload" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Paymark |
"gateway": "paymark" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayMaster |
"gateway": "paymaster" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Payment Fusion |
"gateway": "paymentfusion" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Paymentvision |
"gateway": "paymentvision" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Paymentwall |
"gateway": "paymentwall" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Paymo |
"gateway": "paymo" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Paymob |
"gateway": "gpaymob" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Paymtech |
"gateway": "paymtech" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayNearMe |
"gateway": "paynearme" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Payneteasy |
"gateway": "payneteasy" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Pay.nl |
"gateway": "paynl" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Paynopain |
"gateway": "paynopain" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayOne |
"gateway": "payone" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayOnline |
"gateway": "payonline" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Payoo |
"gateway": "payoo" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayPlus |
"gateway": "payplus" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Payrails |
"gateway": "payrails" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Payrexx |
"gateway": "payrexx" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayRiff |
"gateway": "payriff" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Payrix |
"gateway": "payrix" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Paysafe |
"gateway": "paysafe" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Payscout |
"gateway": "payscout" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Paysend Business |
"gateway": "paysend" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Paysoft |
"gateway": "paysoft" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Pay360 |
"gateway": "pay360" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
paytech |
"gateway": "paytechsolutions" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayTech Ukraine |
"gateway": "paytech" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Paythru |
"gateway": "paythru" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Payture |
"gateway": "payture" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayU |
"gateway": "payu" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayU LATAM |
"gateway": "payulatam" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PAYUNi |
"gateway": "payuni" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayU Romania |
"gateway": "payuro" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayU Russia |
"gateway": "payuru" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PayWay |
"gateway": "payway" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Paywiser |
"gateway": "paywiser" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Pelecard |
"gateway": "pelecard" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Pikassa |
"gateway": "pikassa" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PingPong |
"gateway": "pingpongx" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Pin Payments |
"gateway": "pinpayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Planet |
"gateway": "cccpayment" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PlanetPay |
"gateway": "itcardpaymentservice" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Plategka.com |
"gateway": "plategkacom" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Платон |
"gateway": "platon" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Pomelo |
"gateway": "pomelopay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Portmone |
"gateway": "portmonecom" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Primer |
"gateway": "primer" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Procard |
"gateway": "procard" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
ProcessOut |
"gateway": "processout" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Przelewy24 |
"gateway": "przelewy24" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Промсвязьбанк |
"gateway": "psbank" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
ПСКБ |
"gateway": "pscbru" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
PXP Financial |
"gateway": "pxpfinancial" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Qenta Payment CEE |
"gateway": "qenta" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
QIWI |
"gateway": "qiwi" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Qualpay |
"gateway": "qualpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
QuickPay |
"gateway": "quickpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Qvalent |
"gateway": "qvalent" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Radial |
"gateway": "radial" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Rapyd |
"gateway": "rapyd" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
RBK.money |
"gateway": "rbkmoney" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Rebail Capital |
"gateway": "rebailcapital" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Rebilly |
"gateway": "Rebilly" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Recurly |
"gateway": "recurly" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Reddot |
"gateway": "reddotpayment" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Rede |
"gateway": "rede" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Redsys |
"gateway": "redsys" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Reepay |
"gateway": "reepay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
RocketGate |
"gateway": "rocketgate" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Банк Русский Стандарт |
"gateway": "rsb" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Ryft |
"gateway": "ryft" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Saferpay |
"gateway": "worldlinesaferpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Safexpay |
"gateway": "safexpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Сбербанк |
"gateway": "sberbank" "gatewayMerchantId": "YOUR_ORGANIZATION_NAME" |
SEB Baltic |
"gateway": "sebbaltic" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Sense Bank |
"gateway": "sensebank" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
SensePass |
"gateway": "sensepass" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Shift4 |
"gateway": "shift4payments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Shiji Group |
"gateway": "shijipaymentsolutions" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
SH Start High |
"gateway": "shstartpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
simbasoft |
"gateway": "simbasoft" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Sipay |
"gateway": "sipay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
SoftBank Payment Service |
"gateway": "sbps" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Solid |
"gateway": "solid" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Sony Payment Services |
"gateway": "sonypaymentservices" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Splitit |
"gateway": "splitit" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Spreedly |
"gateway": "spreedly" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Square |
"gateway": "square" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
SredaPay |
"gateway": "sredapay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Stancer |
"gateway": "stancer" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Stripe |
"gateway": "stripe" "stripe:version": "2018-10-31" "stripe:publishableKey": "YOUR_PUBLIC_STRIPE_KEY" |
Suntech |
"gateway": "esafe" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Surfboard Payments |
"gateway": "surfboard" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Svea Bank |
"gateway": "svea" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Swedbank Baltic |
"gateway": "swedbankbaltic" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Swedbank Pay |
"gateway": "payexswedbankpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
TabaPay |
"gateway": "tabapay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
TapPay (Cherri Tech) |
"gateway": "tappay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
TapPayments |
"gateway": "tappayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
tarlanpayments |
"gateway": "tarlanpayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
TAS Link |
"gateway": "taslink" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Tatra banka (CardPay) |
"gateway": "tatrabanka" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" Документация для разработчиков отсутствует |
TEKO |
"gateway": "teko" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
theMAP |
"gateway": "themap" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Till Payments |
"gateway": "tillpayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Тинькофф |
"gateway": "tinkoff" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
TPay |
"gateway": "tpaycom" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
TPay.com |
"gateway": "tpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Transact Campus |
"gateway": "transactcampus" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Transaction Services Network |
"gateway": "tns" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Transpayrent |
"gateway": "transpayrent" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Tranzila |
"gateway": "tranzila" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Tranzzo |
"gateway": "tranzzo" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Tribe Payments |
"gateway": "tribepayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Truevo |
"gateway": "truevo" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
TrustPay |
"gateway": "trustpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Trust Payments |
"gateway": "trustpayments" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Tuna |
"gateway": "tuna" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
2can&ibox |
"gateway": "twocan" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
UAPAY |
"gateway": "uapay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
УБРиР |
"gateway": "ubrrpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Ukrcard |
"gateway": "ukrcardpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
UkrGasBank Pay |
"gateway": "ukrgasbankpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Unibank OJSC |
"gateway": "unibankcheckout" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
unitedfinancialcorporation |
"gateway": "unitedfinancialcorporation" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Uniteller |
"gateway": "uniteller" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Unitpay |
"gateway": "unitpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Unlimint |
"gateway": "unlimint" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Unzer |
"gateway": "unzer" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Unzer Austria |
"gateway": "unzeraustria" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
UPC |
"gateway": "upc" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Upgate |
"gateway": "upgate" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
USAePay |
"gateway": "usaepay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
UseePay |
"gateway": "useepay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Valitor |
"gateway": "valitor" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Vantiv |
"gateway": "vantiv" "vantiv:merchantPayPageId": "YOUR_PAY_PAGE_ID" "vantiv:merchantOrderId": "YOUR_ORDER_ID" "vantiv:merchantTransactionId": "YOUR_TRANSACTION_ID" "vantiv:merchantReportGroup": "*web" |
Verestro |
"gateway": "verestro" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Very Good Security |
"gateway": "verygoodsecurity" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Vindicia |
"gateway": "vindicia" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Viva Wallet |
"gateway": "vivawallet" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
VTEX |
"gateway": "vtex" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Walletdoc |
"gateway": "walletdoc" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Walletto |
"gateway": "walletto" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
WayForPay |
"gateway": "wayforpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
WEAT |
"gateway": "weatpay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
WhenThen |
"gateway": "whenthen" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Windcave |
"gateway": "windcave" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Wirebank |
"gateway": "wirebank" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Wirecard |
"gateway": "wirecard" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
WOOPPAY |
"gateway": "wooppay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
WooshPay |
"gateway": "swooshtransfer" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Worldline (GlobalCollect) |
"gateway": "globalcollect" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Worldline – Ingenico (онлайн-оплата Worldline) |
"gateway": "worldlineingenicoogone" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Worldline Nordics (Worldline Online Checkout) |
"gateway": "worldlineonlinecheckout" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Worldline Sips |
"gateway": "wlsips" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Worldnet |
"gateway": "worldnet" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Worldpay |
"gateway": "worldpay" "gatewayMerchantId": "YOUR_WORLDPAY_MERCHANT_ID" |
Wpay |
"gateway": "wpayaus" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
WSPay |
"gateway": "wspay" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
XPATE |
"gateway": "xpate" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
xpay |
"gateway": "xpaycomua" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
YIĞIM Payment System |
"gateway": "yigim" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" Документация для разработчиков отсутствует |
ЮKassa |
"gateway": "yoomoney" "gatewayMerchantId": "YOUR_SHOP_ID" |
Z-credit |
"gateway": "zcredit" "gatewayMerchantId": "YOUR_SHOP_ID" |
ZEN.com |
"gateway": "zen" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Zest |
"gateway": "zestpayment" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Zuora |
"gateway": "zuora" "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID" |
Тип токенизации PAYMENT_GATEWAY
– наиболее распространенный способ внедрения Google Pay API для оплаты картой. Если ваш поставщик платежных услуг не поддерживается, попробуйте выполнить интеграцию типа DIRECT
. Более подробную информацию можно найти в документации.
Шаг 3. Задайте поддерживаемые платежные системы
Выберите платежные системы, карты которых принимаются в вашем приложении.
Kotlin
private val allowedCardNetworks = JSONArray(listOf( "AMEX", "DISCOVER", "INTERAC", "JCB", "MASTERCARD", "VISA"))
Java
private static JSONArray getAllowedCardNetworks() { return new JSONArray() .put("AMEX") .put("DISCOVER") .put("INTERAC") .put("JCB") .put("MASTERCARD") .put("VISA"); }
Google Pay API может показать результаты поиска карт в архивах Google.com (PAN_ONLY
) или токен устройства на устройстве Android, аутентифицированном с помощью криптограммы 3-D Secure (CRYPTOGRAM_3DS
).
Kotlin
private val allowedCardAuthMethods = JSONArray(listOf( "PAN_ONLY", "CRYPTOGRAM_3DS"))
Java
private static JSONArray getAllowedCardAuthMethods() { return new JSONArray() .put("PAN_ONLY") .put("CRYPTOGRAM_3DS"); }
Дополнительную информацию можно найти в разделе CardParameters
в сведениях об объектах JSON. Список поддерживаемых токенов для устройств Android можно получить через шлюз, а информацию о поддерживаемых платежных системах – у обработчика платежей.
Шаг 4. Укажите поддерживаемые способы оплаты
Указать, что ваше приложение поддерживает способ оплаты CARD
, можно через сочетание методов аутентификации и платежных систем.
Kotlin
private fun baseCardPaymentMethod(): JSONObject { return JSONObject().apply { val parameters = JSONObject().apply { put("allowedAuthMethods", allowedCardAuthMethods) put("allowedCardNetworks", allowedCardNetworks) put("billingAddressRequired", true) put("billingAddressParameters", JSONObject().apply { put("format", "FULL") }) } put("type", "CARD") put("parameters", parameters) } }
Java
private static JSONObject getBaseCardPaymentMethod() throws JSONException { JSONObject cardPaymentMethod = new JSONObject(); cardPaymentMethod.put("type", "CARD"); JSONObject parameters = new JSONObject(); parameters.put("allowedAuthMethods", getAllowedCardAuthMethods()); parameters.put("allowedCardNetworks", getAllowedCardNetworks()); // Optionally, you can add billing address/phone number associated with a CARD payment method. parameters.put("billingAddressRequired", true); JSONObject billingAddressParameters = new JSONObject(); billingAddressParameters.put("format", "FULL"); parameters.put("billingAddressParameters", billingAddressParameters); cardPaymentMethod.put("parameters", parameters); return cardPaymentMethod; }
Расширьте объект базового способа оплаты картой, чтобы указать, какая информация (включая токенизированные платежные данные) должна возвращаться в приложение.
Kotlin
private fun cardPaymentMethod(): JSONObject { val cardPaymentMethod = baseCardPaymentMethod() cardPaymentMethod.put("tokenizationSpecification", gatewayTokenizationSpecification()) return cardPaymentMethod }
Java
private static JSONObject getCardPaymentMethod() throws JSONException { JSONObject cardPaymentMethod = getBaseCardPaymentMethod(); cardPaymentMethod.put("tokenizationSpecification", getGatewayTokenizationSpecification()); return cardPaymentMethod; }
Дополнительную информацию о поддерживаемых параметрах parameters
можно найти в разделе CardParameters
в сведениях об объектах JSON.
Помимо карт (CARD
), в Google Pay поддерживается способ оплаты PAYPAL
. Подробнее о том, как добавить счет PayPal в Google Pay, написано здесь.
Шаг 5. Создайте экземпляр объекта PaymentsClient
Создайте экземпляр PaymentsClient
в методе onCreate
объекта Activity
. Экземпляр PaymentsClient
используется для взаимодействия с Google Pay API.
Kotlin
fun createPaymentsClient(activity: Activity): PaymentsClient { val walletOptions = Wallet.WalletOptions.Builder() .setEnvironment(Constants.PAYMENTS_ENVIRONMENT) .build() return Wallet.getPaymentsClient(activity, walletOptions) }
Java
public static PaymentsClient createPaymentsClient(Activity activity) { Wallet.WalletOptions walletOptions = new Wallet.WalletOptions.Builder().setEnvironment(Constants.PAYMENTS_ENVIRONMENT).build(); return Wallet.getPaymentsClient(activity, walletOptions); }
Шаг 6. Определите готовность к оплате с помощью Google Pay API
Добавьте разрешенные способы оплаты в базовый объект запроса с помощью следующего фрагмента кода:
Kotlin
fun isReadyToPayRequest(): JSONObject? { return try { baseRequest.apply { put("allowedPaymentMethods", JSONArray().put(baseCardPaymentMethod())) } } catch (e: JSONException) { null } }
Java
public static Optional<JSONObject> getIsReadyToPayRequest() { try { JSONObject isReadyToPayRequest = getBaseRequest(); isReadyToPayRequest.put( "allowedPaymentMethods", new JSONArray().put(getBaseCardPaymentMethod())); return Optional.of(isReadyToPayRequest); } catch (JSONException e) { return Optional.empty(); } }
Прежде чем отображать кнопку Google Pay, вызовите isReadyToPay API, чтобы определить, может ли пользователь расплатиться через Google Pay API. Полный список свойств конфигурации можно найти в документации JSON по объекту IsReadyToPayRequest
.
Kotlin
private fun possiblyShowGooglePayButton() { val isReadyToPayJson = PaymentsUtil.isReadyToPayRequest() ?: return val request = IsReadyToPayRequest.fromJson(isReadyToPayJson.toString()) ?: return // The call to isReadyToPay is asynchronous and returns a Task. We need to provide an // OnCompleteListener to be triggered when the result of the call is known. val task = paymentsClient.isReadyToPay(request) task.addOnCompleteListener { completedTask -> try { completedTask.getResult(ApiException::class.java)?.let(::setGooglePayAvailable) } catch (exception: ApiException) { // Process error Log.w("isReadyToPay failed", exception) } } }
Java
private void possiblyShowGooglePayButton() { final Optional<JSONObject> isReadyToPayJson = PaymentsUtil.getIsReadyToPayRequest(); if (!isReadyToPayJson.isPresent()) { return; } // The call to isReadyToPay is asynchronous and returns a Task. We need to provide an // OnCompleteListener to be triggered when the result of the call is known. IsReadyToPayRequest request = IsReadyToPayRequest.fromJson(isReadyToPayJson.get().toString()); Task<Boolean> task = paymentsClient.isReadyToPay(request); task.addOnCompleteListener(this, new OnCompleteListener<Boolean>() { @Override public void onComplete(@NonNull Task<Boolean> task) { if (task.isSuccessful()) { setGooglePayAvailable(task.getResult()); } else { Log.w("isReadyToPay failed", task.getException()); } } }); }
Как показывает пример, лучше всего указать Google Pay в качестве способа оплаты только после получения положительного результата от функции isReadyToPay
. Как правило, кнопка Google Pay отображается в макете include
, когда вы применяете способ оплаты. Более подробную информацию о доступных кнопках оплаты, логотипах и метках Google Pay можно найти в правилах фирменного оформления Google.
Шаг 7. Создайте объект PaymentDataRequest
Объект JSON PaymentDataRequest
описывает информацию, которую нужно запросить у покупателя на странице оплаты Google Pay.
Укажите данные о цене сделки и о ее статусе. Более подробная информация приведена в документации JSON по объекту TransactionInfo
.
В следующем примере показано, как запросить цену, ее статус и сведения о валюте транзакции.
Kotlin
private fun getTransactionInfo(price: String): JSONObject { return JSONObject().apply { put("totalPrice", price) put("totalPriceStatus", "FINAL") put("countryCode", Constants.COUNTRY_CODE) put("currencyCode", Constants.CURRENCY_CODE) } }
Java
private static JSONObject getTransactionInfo(String price) throws JSONException { JSONObject transactionInfo = new JSONObject(); transactionInfo.put("totalPrice", price); transactionInfo.put("totalPriceStatus", "FINAL"); transactionInfo.put("countryCode", Constants.COUNTRY_CODE); transactionInfo.put("currencyCode", Constants.CURRENCY_CODE); transactionInfo.put("checkoutOption", "COMPLETE_IMMEDIATE_PURCHASE"); return transactionInfo; }
Укажите название продавца для пользователей. Более подробная информация приведена в документации JSON по объекту MerchantInfo
.
В примере ниже показано, как получить название продавца.
Kotlin
private val merchantInfo: JSONObject = JSONObject().put("merchantName", "Example Merchant")
Java
private static JSONObject getMerchantInfo() throws JSONException { return new JSONObject().put("merchantName", "Example Merchant"); }
Выберите базовый объект запроса в качестве нового объекта JSON PaymentDataRequest
.
Добавьте способы оплаты, поддерживаемые вашим приложением, с указанием конфигураций дополнительных данных, ожидаемых в ответе. Укажите данные о транзакции и о продавце, отправившем запрос.
В примере ниже показано, как запросить платежные данные:
Kotlin
fun getPaymentDataRequest(price: String): JSONObject? { try { return baseRequest.apply { put("allowedPaymentMethods", JSONArray().put(cardPaymentMethod())) put("transactionInfo", getTransactionInfo(price)) put("merchantInfo", merchantInfo) // An optional shipping address requirement is a top-level property of the // PaymentDataRequest JSON object. val shippingAddressParameters = JSONObject().apply { put("phoneNumberRequired", false) put("allowedCountryCodes", JSONArray(listOf("US", "GB"))) } put("shippingAddressParameters", shippingAddressParameters) put("shippingAddressRequired", true) } } catch (e: JSONException) { return null } }
Java
public static Optional<JSONObject> getPaymentDataRequest(long priceCents) { final String price = PaymentsUtil.centsToString(priceCents); try { JSONObject paymentDataRequest = PaymentsUtil.getBaseRequest(); paymentDataRequest.put( "allowedPaymentMethods", new JSONArray().put(PaymentsUtil.getCardPaymentMethod())); paymentDataRequest.put("transactionInfo", PaymentsUtil.getTransactionInfo(price)); paymentDataRequest.put("merchantInfo", PaymentsUtil.getMerchantInfo()); /* An optional shipping address requirement is a top-level property of the PaymentDataRequest JSON object. */ paymentDataRequest.put("shippingAddressRequired", true); JSONObject shippingAddressParameters = new JSONObject(); shippingAddressParameters.put("phoneNumberRequired", false); JSONArray allowedCountryCodes = new JSONArray(Constants.SHIPPING_SUPPORTED_COUNTRIES); shippingAddressParameters.put("allowedCountryCodes", allowedCountryCodes); paymentDataRequest.put("shippingAddressParameters", shippingAddressParameters); return Optional.of(paymentDataRequest); } catch (JSONException e) { return Optional.empty(); } }
Более подробная информация приведена в документации JSON по объекту PaymentDataRequest
.
Шаг 8. Настройте обработчик жестов пользователей
Чтобы запросить вывод страницы оплаты Google Pay при нажатии пользователем кнопки оплаты Google Pay, задайте параметр OnClickListener
.
Kotlin
googlePayButton.setOnClickListener { requestPayment() }
Java
googlePayButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { requestPayment(view); } });
Объект PaymentDataRequest
– это Parcelable
, который представляет собой запрос платежных данных. Сведения объекта PaymentDataRequest
необходимы для оплаты. Используйте класс AutoResolveHelper
, чтобы автоматически выполнить поставленную задачу Task
. Затем обработайте результат с помощью метода onActivityResult
класса Activity
.
Шаг 9. Обработайте объект ответа
После того как покупатель укажет всю запрашиваемую информацию на странице оплаты Google Pay, объект PaymentData
возвращается в onActivityResult
.
Чтобы передать платежные данные обработчику и выдать подтверждение покупки пользователю, преобразуйте ответ в JSON. Если параметр transactionInfo.totalPriceStatus
, переданный в PaymentDataRequest
, имеет статус ESTIMATED
, необходимо показать итоговую цену до списания средств в рамках возвращенного способа оплаты.
Извлеките токен из ответа paymentData
. Если вы выполняете интеграцию шлюза, передайте этот токен шлюзу, не совершая никаких изменений.
Kotlin
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { when (requestCode) { // Value passed in AutoResolveHelper LOAD_PAYMENT_DATA_REQUEST_CODE -> { when (resultCode) { RESULT_OK -> data?.let { intent -> PaymentData.getFromIntent(intent)?.let(::handlePaymentSuccess) } RESULT_CANCELED -> { // The user cancelled the payment attempt } AutoResolveHelper.RESULT_ERROR -> { AutoResolveHelper.getStatusFromIntent(data)?.let { handleError(it.statusCode) } } } // Re-enables the Google Pay payment button. googlePayButton.isClickable = true } } }
Java
public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { // value passed in AutoResolveHelper case LOAD_PAYMENT_DATA_REQUEST_CODE: switch (resultCode) { case Activity.RESULT_OK: PaymentData paymentData = PaymentData.getFromIntent(data); handlePaymentSuccess(paymentData); break; case Activity.RESULT_CANCELED: // The user cancelled the payment attempt break; case AutoResolveHelper.RESULT_ERROR: Status status = AutoResolveHelper.getStatusFromIntent(data); handleError(status.getStatusCode()); break; } // Re-enables the Google Pay payment button. googlePayButton.setClickable(true); } }
Дополнительную информацию о содержании и структуре ответа можно найти в документации JSON по объекту PaymentData
.
Выводы
Далее представлен полный пример правильно настроенного проекта. Инструкции см. в разделе Настройте ваш проект.
CheckoutActivity.kt (Kotlin)
В рамках данного примера Activity
предполагается, что кнопка оплаты Google Pay с атрибутом id
в googlepay_button
имеется в макете.
/* * Copyright 2018 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.android.gms.samples.wallet.activity import android.app.Activity import android.content.Intent import android.os.Bundle import android.text.Html import android.util.Log import android.view.View import android.widget.Toast import com.google.android.gms.common.api.ApiException import com.google.android.gms.samples.wallet.util.PaymentsUtil import com.google.android.gms.samples.wallet.R import com.google.android.gms.samples.wallet.util.Json import com.google.android.gms.wallet.* import kotlinx.android.synthetic.main.activity_checkout.* import org.json.JSONArray import org.json.JSONException import org.json.JSONObject /** * Checkout implementation for the app */ class CheckoutActivity : Activity() { private val SHIPPING_COST_CENTS = 9 * PaymentsUtil.CENTS.toLong() /** * A client for interacting with the Google Pay API. * * @see [PaymentsClient](https://developers.google.com/android/reference/com/google/android/gms/wallet/PaymentsClient) */ private lateinit var paymentsClient: PaymentsClient private lateinit var garmentList: JSONArray private lateinit var selectedGarment: JSONObject /** * Arbitrarily-picked constant integer you define to track a request for payment data activity. * * @value #LOAD_PAYMENT_DATA_REQUEST_CODE */ private val LOAD_PAYMENT_DATA_REQUEST_CODE = 991 /** * Initialize the Google Pay API on creation of the activity * * @see Activity.onCreate */ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_checkout) // Set up the mock information for our item in the UI. selectedGarment = fetchRandomGarment() displayGarment(selectedGarment) // Initialize a Google Pay API client for an environment suitable for testing. // It's recommended to create the PaymentsClient object inside of the onCreate method. paymentsClient = PaymentsUtil.createPaymentsClient(this) possiblyShowGooglePayButton() googlePayButton.setOnClickListener { requestPayment() } } /** * Determine the viewer's ability to pay with a payment method supported by your app and display a * Google Pay payment button. * * @see [](https://developers.google.com/android/reference/com/google/android/gms/wallet/PaymentsClient.html.isReadyToPay ) */ private fun possiblyShowGooglePayButton() { val isReadyToPayJson = PaymentsUtil.isReadyToPayRequest() ?: return val request = IsReadyToPayRequest.fromJson(isReadyToPayJson.toString()) ?: return // The call to isReadyToPay is asynchronous and returns a Task. We need to provide an // OnCompleteListener to be triggered when the result of the call is known. val task = paymentsClient.isReadyToPay(request) task.addOnCompleteListener { completedTask -> try { completedTask.getResult(ApiException::class.java)?.let(::setGooglePayAvailable) } catch (exception: ApiException) { // Process error Log.w("isReadyToPay failed", exception) } } } /** * If isReadyToPay returned `true`, show the button and hide the "checking" text. Otherwise, * notify the user that Google Pay is not available. Please adjust to fit in with your current * user flow. You are not required to explicitly let the user know if isReadyToPay returns `false`. * * @param available isReadyToPay API response. */ private fun setGooglePayAvailable(available: Boolean) { if (available) { googlePayButton.visibility = View.VISIBLE } else { Toast.makeText( this, "Unfortunately, Google Pay is not available on this device", Toast.LENGTH_LONG).show(); } } private fun requestPayment() { // Disables the button to prevent multiple clicks. googlePayButton.isClickable = false // The price provided to the API should include taxes and shipping. // This price is not displayed to the user. val garmentPrice = selectedGarment.getDouble("price") val priceCents = Math.round(garmentPrice * PaymentsUtil.CENTS.toLong()) + SHIPPING_COST_CENTS val paymentDataRequestJson = PaymentsUtil.getPaymentDataRequest(priceCents) if (paymentDataRequestJson == null) { Log.e("RequestPayment", "Can't fetch payment data request") return } val request = PaymentDataRequest.fromJson(paymentDataRequestJson.toString()) // Since loadPaymentData may show the UI asking the user to select a payment method, we use // AutoResolveHelper to wait for the user interacting with it. Once completed, // onActivityResult will be called with the result. if (request != null) { AutoResolveHelper.resolveTask( paymentsClient.loadPaymentData(request), this, LOAD_PAYMENT_DATA_REQUEST_CODE) } } /** * Handle a resolved activity from the Google Pay payment sheet. * * @param requestCode Request code originally supplied to AutoResolveHelper in requestPayment(). * @param resultCode Result code returned by the Google Pay API. * @param data Intent from the Google Pay API containing payment or error data. * @see [Getting a result * from an Activity](https://developer.android.com/training/basics/intents/result) */ public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { when (requestCode) { // Value passed in AutoResolveHelper LOAD_PAYMENT_DATA_REQUEST_CODE -> { when (resultCode) { RESULT_OK -> data?.let { intent -> PaymentData.getFromIntent(intent)?.let(::handlePaymentSuccess) } RESULT_CANCELED -> { // The user cancelled the payment attempt } AutoResolveHelper.RESULT_ERROR -> { AutoResolveHelper.getStatusFromIntent(data)?.let { handleError(it.statusCode) } } } // Re-enables the Google Pay payment button. googlePayButton.isClickable = true } } } /** * PaymentData response object contains the payment information, as well as any additional * requested information, such as billing and shipping address. * * @param paymentData A response object returned by Google after a payer approves payment. * @see [Payment * Data](https://developers.google.com/pay/api/android/reference/object.PaymentData) */ private fun handlePaymentSuccess(paymentData: PaymentData) { val paymentInformation = paymentData.toJson() ?: return try { // Token will be null if PaymentDataRequest was not constructed using fromJson(String). val paymentMethodData = JSONObject(paymentInformation).getJSONObject("paymentMethodData") val billingName = paymentMethodData.getJSONObject("info") .getJSONObject("billingAddress").getString("name") Log.d("BillingName", billingName) Toast.makeText(this, getString(R.string.payments_show_name, billingName), Toast.LENGTH_LONG).show() // Logging token string. Log.d("GooglePaymentToken", paymentMethodData .getJSONObject("tokenizationData") .getString("token")) } catch (e: JSONException) { Log.e("handlePaymentSuccess", "Error: " + e.toString()) } } /** * At this stage, the user has already seen a popup informing them an error occurred. Normally, * only logging is required. * * @param statusCode will hold the value of any constant from CommonStatusCode or one of the * WalletConstants.ERROR_CODE_* constants. * @see [ * Wallet Constants Library](https://developers.google.com/android/reference/com/google/android/gms/wallet/WalletConstants.constant-summary) */ private fun handleError(statusCode: Int) { Log.w("loadPaymentData failed", String.format("Error code: %d", statusCode)) } private fun fetchRandomGarment() : JSONObject { if (!::garmentList.isInitialized) { garmentList = Json.readFromResources(this, R.raw.tshirts) } val randomIndex:Int = Math.round(Math.random() * (garmentList.length() - 1)).toInt() return garmentList.getJSONObject(randomIndex) } private fun displayGarment(garment:JSONObject) { detailTitle.setText(garment.getString("title")) detailPrice.setText("\$${garment.getString("price")}") val escapedHtmlText:String = Html.fromHtml(garment.getString("description")).toString() detailDescription.setText(Html.fromHtml(escapedHtmlText)) val imageUri = "@drawable/${garment.getString("image")}" val imageResource = resources.getIdentifier(imageUri, null, packageName) detailImage.setImageResource(imageResource) } }
PaymentsUtil.kt (Kotlin)
Ниже приведен пример файла для создания объектов JSON, используемых для построения запросов IsReadyToPayRequest
или PaymentDataRequest
.
/* * Copyright 2017 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.android.gms.samples.wallet.util import android.app.Activity import com.google.android.gms.samples.wallet.Constants import com.google.android.gms.wallet.PaymentsClient import com.google.android.gms.wallet.Wallet import org.json.JSONArray import org.json.JSONException import org.json.JSONObject import java.math.BigDecimal import java.math.RoundingMode /** * Contains helper static methods for dealing with the Payments API. * * Many of the parameters used in the code are optional and are set here merely to call out their * existence. Please consult the documentation to learn more and feel free to remove ones not * relevant to your implementation. */ object PaymentsUtil { val CENTS = BigDecimal(100) /** * Create a Google Pay API base request object with properties used in all requests. * * @return Google Pay API base request object. * @throws JSONException */ private val baseRequest = JSONObject().apply { put("apiVersion", 2) put("apiVersionMinor", 0) } /** * Gateway Integration: Identify your gateway and your app's gateway merchant identifier. * * * The Google Pay API response will return an encrypted payment method capable of being charged * by a supported gateway after payer authorization. * * * TODO: Check with your gateway on the parameters to pass and modify them in Constants.java. * * @return Payment data tokenization for the CARD payment method. * @throws JSONException * @see [PaymentMethodTokenizationSpecification](https://developers.google.com/pay/api/android/reference/object.PaymentMethodTokenizationSpecification) */ private fun gatewayTokenizationSpecification(): JSONObject { return JSONObject().apply { put("type", "PAYMENT_GATEWAY") put("parameters", JSONObject(Constants.PAYMENT_GATEWAY_TOKENIZATION_PARAMETERS)) } } /** * `DIRECT` Integration: Decrypt a response directly on your servers. This configuration has * additional data security requirements from Google and additional PCI DSS compliance complexity. * * * Please refer to the documentation for more information about `DIRECT` integration. The * type of integration you use depends on your payment processor. * * @return Payment data tokenization for the CARD payment method. * @throws JSONException * @see [PaymentMethodTokenizationSpecification](https://developers.google.com/pay/api/android/reference/object.PaymentMethodTokenizationSpecification) */ private fun directTokenizationSpecification(): JSONObject { if (Constants.DIRECT_TOKENIZATION_PUBLIC_KEY == "REPLACE_ME" || (Constants.DIRECT_TOKENIZATION_PARAMETERS.isEmpty() || Constants.DIRECT_TOKENIZATION_PUBLIC_KEY.isEmpty())) { throw RuntimeException( "Please edit the Constants.java file to add protocol version & public key.") } return JSONObject().apply { put("type", "DIRECT") put("parameters", JSONObject(Constants.DIRECT_TOKENIZATION_PARAMETERS)) } } /** * Card networks supported by your app and your gateway. * * * TODO: Confirm card networks supported by your app and gateway & update in Constants.java. * * @return Allowed card networks * @see [CardParameters](https://developers.google.com/pay/api/android/reference/object.CardParameters) */ private val allowedCardNetworks = JSONArray(Constants.SUPPORTED_NETWORKS) /** * Card authentication methods supported by your app and your gateway. * * * TODO: Confirm your processor supports Android device tokens on your supported card networks * and make updates in Constants.java. * * @return Allowed card authentication methods. * @see [CardParameters](https://developers.google.com/pay/api/android/reference/object.CardParameters) */ private val allowedCardAuthMethods = JSONArray(Constants.SUPPORTED_METHODS) /** * Describe your app's support for the CARD payment method. * * * The provided properties are applicable to both an IsReadyToPayRequest and a * PaymentDataRequest. * * @return A CARD PaymentMethod object describing accepted cards. * @throws JSONException * @see [PaymentMethod](https://developers.google.com/pay/api/android/reference/object.PaymentMethod) */ // Optionally, you can add billing address/phone number associated with a CARD payment method. private fun baseCardPaymentMethod(): JSONObject { return JSONObject().apply { val parameters = JSONObject().apply { put("allowedAuthMethods", allowedCardAuthMethods) put("allowedCardNetworks", allowedCardNetworks) put("billingAddressRequired", true) put("billingAddressParameters", JSONObject().apply { put("format", "FULL") }) } put("type", "CARD") put("parameters", parameters) } } /** * Describe the expected returned payment data for the CARD payment method * * @return A CARD PaymentMethod describing accepted cards and optional fields. * @throws JSONException * @see [PaymentMethod](https://developers.google.com/pay/api/android/reference/object.PaymentMethod) */ private fun cardPaymentMethod(): JSONObject { val cardPaymentMethod = baseCardPaymentMethod() cardPaymentMethod.put("tokenizationSpecification", gatewayTokenizationSpecification()) return cardPaymentMethod } /** * An object describing accepted forms of payment by your app, used to determine a viewer's * readiness to pay. * * @return API version and payment methods supported by the app. * @see [IsReadyToPayRequest](https://developers.google.com/pay/api/android/reference/object.IsReadyToPayRequest) */ fun isReadyToPayRequest(): JSONObject? { return try { baseRequest.apply { put("allowedPaymentMethods", JSONArray().put(baseCardPaymentMethod())) } } catch (e: JSONException) { null } } /** * Information about the merchant requesting payment information * * @return Information about the merchant. * @throws JSONException * @see [MerchantInfo](https://developers.google.com/pay/api/android/reference/object.MerchantInfo) */ private val merchantInfo: JSONObject = JSONObject().put("merchantName", "Example Merchant") /** * Creates an instance of [PaymentsClient] for use in an [Activity] using the * environment and theme set in [Constants]. * * @param activity is the caller's activity. */ fun createPaymentsClient(activity: Activity): PaymentsClient { val walletOptions = Wallet.WalletOptions.Builder() .setEnvironment(Constants.PAYMENTS_ENVIRONMENT) .build() return Wallet.getPaymentsClient(activity, walletOptions) } /** * Provide Google Pay API with a payment amount, currency, and amount status. * * @return information about the requested payment. * @throws JSONException * @see [TransactionInfo](https://developers.google.com/pay/api/android/reference/object.TransactionInfo) */ @Throws(JSONException::class) private fun getTransactionInfo(price: String): JSONObject { return JSONObject().apply { put("totalPrice", price) put("totalPriceStatus", "FINAL") put("countryCode", Constants.COUNTRY_CODE) put("currencyCode", Constants.CURRENCY_CODE) } } /** * An object describing information requested in a Google Pay payment sheet * * @return Payment data expected by your app. * @see [PaymentDataRequest](https://developers.google.com/pay/api/android/reference/object.PaymentDataRequest) */ fun getPaymentDataRequest(priceCemts: Long): JSONObject? { return try { baseRequest.apply { put("allowedPaymentMethods", JSONArray().put(cardPaymentMethod())) put("transactionInfo", getTransactionInfo(priceCemts.centsToString())) put("merchantInfo", merchantInfo) // An optional shipping address requirement is a top-level property of the // PaymentDataRequest JSON object. val shippingAddressParameters = JSONObject().apply { put("phoneNumberRequired", false) put("allowedCountryCodes", JSONArray(listOf("US", "GB"))) } put("shippingAddressParameters", shippingAddressParameters) put("shippingAddressRequired", true) } } catch (e: JSONException) { null } } } /** * Converts cents to a string format accepted by [PaymentsUtil.getPaymentDataRequest]. * * @param cents value of the price. */ fun Long.centsToString() = BigDecimal(this) .divide(PaymentsUtil.CENTS) .setScale(2, RoundingMode.HALF_EVEN) .toString()
CheckoutActivity.java (Java)
В рамках данного примера Activity
предполагается, что кнопка оплаты Google Pay с атрибутом id
в googlepay_button
имеется в макете.
/* * Copyright 2020 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.android.gms.samples.wallet.activity; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.text.Html; import android.util.Log; import android.view.View; import android.widget.Toast; import com.google.android.gms.common.api.Status; import com.google.android.gms.samples.wallet.databinding.ActivityCheckoutBinding; import com.google.android.gms.samples.wallet.util.PaymentsUtil; import com.google.android.gms.samples.wallet.R; import com.google.android.gms.samples.wallet.util.Json; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import com.google.android.gms.wallet.AutoResolveHelper; import com.google.android.gms.wallet.IsReadyToPayRequest; import com.google.android.gms.wallet.PaymentData; import com.google.android.gms.wallet.PaymentDataRequest; import com.google.android.gms.wallet.PaymentsClient; import java.util.Locale; import java.util.Optional; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; /** * Checkout implementation for the app */ public class CheckoutActivity extends AppCompatActivity { // Arbitrarily-picked constant integer you define to track a request for payment data activity. private static final int LOAD_PAYMENT_DATA_REQUEST_CODE = 991; private static final long SHIPPING_COST_CENTS = 90 * PaymentsUtil.CENTS_IN_A_UNIT.longValue(); // A client for interacting with the Google Pay API. private PaymentsClient paymentsClient; private ActivityCheckoutBinding layoutBinding; private View googlePayButton; private JSONArray garmentList; private JSONObject selectedGarment; /** * Initialize the Google Pay API on creation of the activity * * @see Activity#onCreate(android.os.Bundle) */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initializeUi(); // Set up the mock information for our item in the UI. try { selectedGarment = fetchRandomGarment(); displayGarment(selectedGarment); } catch (JSONException e) { throw new RuntimeException("The list of garments cannot be loaded"); } // Initialize a Google Pay API client for an environment suitable for testing. // It's recommended to create the PaymentsClient object inside of the onCreate method. paymentsClient = PaymentsUtil.createPaymentsClient(this); possiblyShowGooglePayButton(); } /** * Handle a resolved activity from the Google Pay payment sheet. * * @param requestCode Request code originally supplied to AutoResolveHelper in requestPayment(). * @param resultCode Result code returned by the Google Pay API. * @param data Intent from the Google Pay API containing payment or error data. * @see <a href="https://developer.android.com/training/basics/intents/result">Getting a result * from an Activity</a> */ @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { // value passed in AutoResolveHelper case LOAD_PAYMENT_DATA_REQUEST_CODE: switch (resultCode) { case Activity.RESULT_OK: PaymentData paymentData = PaymentData.getFromIntent(data); handlePaymentSuccess(paymentData); break; case Activity.RESULT_CANCELED: // The user cancelled the payment attempt break; case AutoResolveHelper.RESULT_ERROR: Status status = AutoResolveHelper.getStatusFromIntent(data); handleError(status.getStatusCode()); break; } // Re-enables the Google Pay payment button. googlePayButton.setClickable(true); } } private void initializeUi() { // Use view binding to access the UI elements layoutBinding = ActivityCheckoutBinding.inflate(getLayoutInflater()); setContentView(layoutBinding.getRoot()); // The Google Pay button is a layout file – take the root view googlePayButton = layoutBinding.googlePayButton.getRoot(); googlePayButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { requestPayment(view); } }); } private void displayGarment(JSONObject garment) throws JSONException { layoutBinding.detailTitle.setText(garment.getString("title")); layoutBinding.detailPrice.setText( String.format(Locale.getDefault(), "$%.2f", garment.getDouble("price"))); final String escapedHtmlText = Html.fromHtml( garment.getString("description"), Html.FROM_HTML_MODE_COMPACT).toString(); layoutBinding.detailDescription.setText(Html.fromHtml( escapedHtmlText, Html.FROM_HTML_MODE_COMPACT)); final String imageUri = String.format("@drawable/%s", garment.getString("image")); final int imageResource = getResources().getIdentifier(imageUri, null, getPackageName()); layoutBinding.detailImage.setImageResource(imageResource); } /** * Determine the viewer's ability to pay with a payment method supported by your app and display a * Google Pay payment button. * * @see <a href="https://developers.google.com/android/reference/com/google/android/gms/wallet/ * PaymentsClient.html#isReadyToPay(com.google.android.gms.wallet. * IsReadyToPayRequest)">PaymentsClient#IsReadyToPay</a> */ private void possiblyShowGooglePayButton() { final Optional<JSONObject> isReadyToPayJson = PaymentsUtil.getIsReadyToPayRequest(); if (!isReadyToPayJson.isPresent()) { return; } // The call to isReadyToPay is asynchronous and returns a Task. We need to provide an // OnCompleteListener to be triggered when the result of the call is known. IsReadyToPayRequest request = IsReadyToPayRequest.fromJson(isReadyToPayJson.get().toString()); Task<Boolean> task = paymentsClient.isReadyToPay(request); task.addOnCompleteListener(this, new OnCompleteListener<Boolean>() { @Override public void onComplete(@NonNull Task<Boolean> task) { if (task.isSuccessful()) { setGooglePayAvailable(task.getResult()); } else { Log.w("isReadyToPay failed", task.getException()); } } }); } /** * If isReadyToPay returned {@code true}, show the button and hide the "checking" text. Otherwise, * notify the user that Google Pay is not available. Please adjust to fit in with your current * user flow. You are not required to explicitly let the user know if isReadyToPay returns {@code * false}. * * @param available isReadyToPay API response. */ private void setGooglePayAvailable(boolean available) { if (available) { googlePayButton.setVisibility(View.VISIBLE); } else { Toast.makeText(this, R.string.googlepay_status_unavailable, Toast.LENGTH_LONG).show(); } } /** * PaymentData response object contains the payment information, as well as any additional * requested information, such as billing and shipping address. * * @param paymentData A response object returned by Google after a payer approves payment. * @see <a href="https://developers.google.com/pay/api/android/reference/ * object#PaymentData">PaymentData</a> */ private void handlePaymentSuccess(PaymentData paymentData) { // Token will be null if PaymentDataRequest was not constructed using fromJson(String). final String paymentInfo = paymentData.toJson(); if (paymentInfo == null) { return; } try { JSONObject paymentMethodData = new JSONObject(paymentInfo).getJSONObject("paymentMethodData"); // If the gateway is set to "example", no payment information is returned - instead, the // token will only consist of "examplePaymentMethodToken". final JSONObject tokenizationData = paymentMethodData.getJSONObject("tokenizationData"); final String token = tokenizationData.getString("token"); final JSONObject info = paymentMethodData.getJSONObject("info"); final String billingName = info.getJSONObject("billingAddress").getString("name"); Toast.makeText( this, getString(R.string.payments_show_name, billingName), Toast.LENGTH_LONG).show(); // Logging token string. Log.d("Google Pay token: ", token); } catch (JSONException e) { throw new RuntimeException("The selected garment cannot be parsed from the list of elements"); } } /** * At this stage, the user has already seen a popup informing them an error occurred. Normally, * only logging is required. * * @param statusCode will hold the value of any constant from CommonStatusCode or one of the * WalletConstants.ERROR_CODE_* constants. * @see <a href="https://developers.google.com/android/reference/com/google/android/gms/wallet/ * WalletConstants#constant-summary">Wallet Constants Library</a> */ private void handleError(int statusCode) { Log.e("loadPaymentData failed", String.format("Error code: %d", statusCode)); } public void requestPayment(View view) { // Disables the button to prevent multiple clicks. googlePayButton.setClickable(false); // The price provided to the API should include taxes and shipping. // This price is not displayed to the user. try { double garmentPrice = selectedGarment.getDouble("price"); long garmentPriceCents = Math.round(garmentPrice * PaymentsUtil.CENTS_IN_A_UNIT.longValue()); long priceCents = garmentPriceCents + SHIPPING_COST_CENTS; Optional<JSONObject> paymentDataRequestJson = PaymentsUtil.getPaymentDataRequest(priceCents); if (!paymentDataRequestJson.isPresent()) { return; } PaymentDataRequest request = PaymentDataRequest.fromJson(paymentDataRequestJson.get().toString()); // Since loadPaymentData may show the UI asking the user to select a payment method, we use // AutoResolveHelper to wait for the user interacting with it. Once completed, // onActivityResult will be called with the result. if (request != null) { AutoResolveHelper.resolveTask( paymentsClient.loadPaymentData(request), this, LOAD_PAYMENT_DATA_REQUEST_CODE); } } catch (JSONException e) { throw new RuntimeException("The price cannot be deserialized from the JSON object."); } } private JSONObject fetchRandomGarment() { // Only load the list of items if it has not been loaded before if (garmentList == null) { garmentList = Json.readFromResources(this, R.raw.tshirts); } // Take a random element from the list int randomIndex = Math.toIntExact(Math.round(Math.random() * (garmentList.length() - 1))); try { return garmentList.getJSONObject(randomIndex); } catch (JSONException e) { throw new RuntimeException("The index specified is out of bounds."); } } }
PaymentsUtil.java (Java)
Ниже приведен пример файла для создания объектов JSON, используемых для построения запросов IsReadyToPayRequest
или PaymentDataRequest
.
/* * Copyright 2020 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.android.gms.samples.wallet.util; import android.app.Activity; import com.google.android.gms.samples.wallet.Constants; import com.google.android.gms.wallet.PaymentsClient; import com.google.android.gms.wallet.Wallet; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Optional; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; /** * Contains helper static methods for dealing with the Payments API. * * <p>Many of the parameters used in the code are optional and are set here merely to call out their * existence. Please consult the documentation to learn more and feel free to remove ones not * relevant to your implementation. */ public class PaymentsUtil { public static final BigDecimal CENTS_IN_A_UNIT = new BigDecimal(100d); /** * Create a Google Pay API base request object with properties used in all requests. * * @return Google Pay API base request object. * @throws JSONException */ private static JSONObject getBaseRequest() throws JSONException { return new JSONObject().put("apiVersion", 2).put("apiVersionMinor", 0); } /** * Creates an instance of {@link PaymentsClient} for use in an {@link Activity} using the * environment and theme set in {@link Constants}. * * @param activity is the caller's activity. */ public static PaymentsClient createPaymentsClient(Activity activity) { Wallet.WalletOptions walletOptions = new Wallet.WalletOptions.Builder().setEnvironment(Constants.PAYMENTS_ENVIRONMENT).build(); return Wallet.getPaymentsClient(activity, walletOptions); } /** * Gateway Integration: Identify your gateway and your app's gateway merchant identifier. * * <p>The Google Pay API response will return an encrypted payment method capable of being charged * by a supported gateway after payer authorization. * * <p>TODO: Check with your gateway on the parameters to pass and modify them in Constants.java. * * @return Payment data tokenization for the CARD payment method. * @throws JSONException * @see <a href= * "https://developers.google.com/pay/api/android/reference/object#PaymentMethodTokenizationSpecification">PaymentMethodTokenizationSpecification</a> */ private static JSONObject getGatewayTokenizationSpecification() throws JSONException { return new JSONObject() {{ put("type", "PAYMENT_GATEWAY"); put("parameters", new JSONObject() {{ put("gateway", "example"); put("gatewayMerchantId", "exampleGatewayMerchantId"); }}); }}; } /** * {@code DIRECT} Integration: Decrypt a response directly on your servers. This configuration has * additional data security requirements from Google and additional PCI DSS compliance complexity. * * <p>Please refer to the documentation for more information about {@code DIRECT} integration. The * type of integration you use depends on your payment processor. * * @return Payment data tokenization for the CARD payment method. * @throws JSONException * @see <a * href="https://developers.google.com/pay/api/android/reference/object#PaymentMethodTokenizationSpecification">PaymentMethodTokenizationSpecification</a> */ private static JSONObject getDirectTokenizationSpecification() throws JSONException, RuntimeException { if (Constants.DIRECT_TOKENIZATION_PARAMETERS.isEmpty() || Constants.DIRECT_TOKENIZATION_PUBLIC_KEY.isEmpty() || Constants.DIRECT_TOKENIZATION_PUBLIC_KEY == null || Constants.DIRECT_TOKENIZATION_PUBLIC_KEY == "REPLACE_ME") { throw new RuntimeException( "Please edit the Constants.java file to add protocol version & public key."); } JSONObject tokenizationSpecification = new JSONObject(); tokenizationSpecification.put("type", "DIRECT"); JSONObject parameters = new JSONObject(Constants.DIRECT_TOKENIZATION_PARAMETERS); tokenizationSpecification.put("parameters", parameters); return tokenizationSpecification; } /** * Card networks supported by your app and your gateway. * * <p>TODO: Confirm card networks supported by your app and gateway & update in Constants.java. * * @return Allowed card networks * @see <a * href="https://developers.google.com/pay/api/android/reference/object#CardParameters">CardParameters</a> */ private static JSONArray getAllowedCardNetworks() { return new JSONArray(Constants.SUPPORTED_NETWORKS); } /** * Card authentication methods supported by your app and your gateway. * * <p>TODO: Confirm your processor supports Android device tokens on your supported card networks * and make updates in Constants.java. * * @return Allowed card authentication methods. * @see <a * href="https://developers.google.com/pay/api/android/reference/object#CardParameters">CardParameters</a> */ private static JSONArray getAllowedCardAuthMethods() { return new JSONArray(Constants.SUPPORTED_METHODS); } /** * Describe your app's support for the CARD payment method. * * <p>The provided properties are applicable to both an IsReadyToPayRequest and a * PaymentDataRequest. * * @return A CARD PaymentMethod object describing accepted cards. * @throws JSONException * @see <a * href="https://developers.google.com/pay/api/android/reference/object#PaymentMethod">PaymentMethod</a> */ private static JSONObject getBaseCardPaymentMethod() throws JSONException { JSONObject cardPaymentMethod = new JSONObject(); cardPaymentMethod.put("type", "CARD"); JSONObject parameters = new JSONObject(); parameters.put("allowedAuthMethods", getAllowedCardAuthMethods()); parameters.put("allowedCardNetworks", getAllowedCardNetworks()); // Optionally, you can add billing address/phone number associated with a CARD payment method. parameters.put("billingAddressRequired", true); JSONObject billingAddressParameters = new JSONObject(); billingAddressParameters.put("format", "FULL"); parameters.put("billingAddressParameters", billingAddressParameters); cardPaymentMethod.put("parameters", parameters); return cardPaymentMethod; } /** * Describe the expected returned payment data for the CARD payment method * * @return A CARD PaymentMethod describing accepted cards and optional fields. * @throws JSONException * @see <a * href="https://developers.google.com/pay/api/android/reference/object#PaymentMethod">PaymentMethod</a> */ private static JSONObject getCardPaymentMethod() throws JSONException { JSONObject cardPaymentMethod = getBaseCardPaymentMethod(); cardPaymentMethod.put("tokenizationSpecification", getGatewayTokenizationSpecification()); return cardPaymentMethod; } /** * An object describing accepted forms of payment by your app, used to determine a viewer's * readiness to pay. * * @return API version and payment methods supported by the app. * @see <a * href="https://developers.google.com/pay/api/android/reference/object#IsReadyToPayRequest">IsReadyToPayRequest</a> */ public static Optional<JSONObject> getIsReadyToPayRequest() { try { JSONObject isReadyToPayRequest = getBaseRequest(); isReadyToPayRequest.put( "allowedPaymentMethods", new JSONArray().put(getBaseCardPaymentMethod())); return Optional.of(isReadyToPayRequest); } catch (JSONException e) { return Optional.empty(); } } /** * Provide Google Pay API with a payment amount, currency, and amount status. * * @return information about the requested payment. * @throws JSONException * @see <a * href="https://developers.google.com/pay/api/android/reference/object#TransactionInfo">TransactionInfo</a> */ private static JSONObject getTransactionInfo(String price) throws JSONException { JSONObject transactionInfo = new JSONObject(); transactionInfo.put("totalPrice", price); transactionInfo.put("totalPriceStatus", "FINAL"); transactionInfo.put("countryCode", Constants.COUNTRY_CODE); transactionInfo.put("currencyCode", Constants.CURRENCY_CODE); transactionInfo.put("checkoutOption", "COMPLETE_IMMEDIATE_PURCHASE"); return transactionInfo; } /** * Information about the merchant requesting payment information * * @return Information about the merchant. * @throws JSONException * @see <a * href="https://developers.google.com/pay/api/android/reference/object#MerchantInfo">MerchantInfo</a> */ private static JSONObject getMerchantInfo() throws JSONException { return new JSONObject().put("merchantName", "Example Merchant"); } /** * An object describing information requested in a Google Pay payment sheet * * @return Payment data expected by your app. * @see <a * href="https://developers.google.com/pay/api/android/reference/object#PaymentDataRequest">PaymentDataRequest</a> */ public static Optional<JSONObject> getPaymentDataRequest(long priceCents) { final String price = PaymentsUtil.centsToString(priceCents); try { JSONObject paymentDataRequest = PaymentsUtil.getBaseRequest(); paymentDataRequest.put( "allowedPaymentMethods", new JSONArray().put(PaymentsUtil.getCardPaymentMethod())); paymentDataRequest.put("transactionInfo", PaymentsUtil.getTransactionInfo(price)); paymentDataRequest.put("merchantInfo", PaymentsUtil.getMerchantInfo()); /* An optional shipping address requirement is a top-level property of the PaymentDataRequest JSON object. */ paymentDataRequest.put("shippingAddressRequired", true); JSONObject shippingAddressParameters = new JSONObject(); shippingAddressParameters.put("phoneNumberRequired", false); JSONArray allowedCountryCodes = new JSONArray(Constants.SHIPPING_SUPPORTED_COUNTRIES); shippingAddressParameters.put("allowedCountryCodes", allowedCountryCodes); paymentDataRequest.put("shippingAddressParameters", shippingAddressParameters); return Optional.of(paymentDataRequest); } catch (JSONException e) { return Optional.empty(); } } /** * Converts cents to a string format accepted by {@link PaymentsUtil#getPaymentDataRequest}. * * @param cents value of the price in cents. */ public static String centsToString(long cents) { return new BigDecimal(cents) .divide(CENTS_IN_A_UNIT, RoundingMode.HALF_EVEN) .setScale(2, RoundingMode.HALF_EVEN) .toString(); } }