# Google Pay on Android Accept Google Pay in your Android application using Finix. This guide details how to get started accepting Google Pay on Android devices using Finix. Dues and Assessments We recommend that you pass the address field listed in the steps below. If the address is not passed, you will be charged additional dues and assessments per transaction from the card network. ## Step 1: Onboard with Google Start by familiarizing yourself with [the prerequisites](/guides/online-payments/digital-wallets/google-pay) for using Google Pay with Finix. ## Step 2: Define Google Pay API Version Declare the version of the Google Pay API that your application uses. The major and minor versions affect the fields expected in each passed object and are included in the response. Create a base request object that contains properties that are present in all other request objects. Kotlin ```kotlin Google Pay API Version private val baseRequest = JSONObject() .put("apiVersion", 2) .put("apiVersionMinor", 0) ``` Java ```java Google Pay API Version private static JSONObject getBaseRequest() throws JSONException { return new JSONObject() .put("apiVersion", 2) .put("apiVersionMinor", 0); } ``` ## Step 3: Request a Finix Payment Token Now that you've defined your Google Pay API Version, request a Finix payment token. - `gateway` should be set to `finix` - `gatewayMerchantId` should be set to the **application owner identity** or **merchant owner identity**. To choose the appropriate Identity ID, see [Choose Merchant Identifier Value](https://docs.finix.com/guides/online-payments/digital-wallets/google-pay). Kotlin ```kotlin Google Pay Tokenization Specification private fun gatewayTokenizationSpecification(): JSONObject { return JSONObject().apply { put("type", "PAYMENT_GATEWAY") put("parameters", JSONObject(mapOf( "gateway" to "finix", "gatewayMerchantId" to "IDxxx"))) } } ``` Java ```java Google Pay Tokenization Specification private static JSONObject getGatewayTokenizationSpecification() throws JSONException { return new JSONObject() .put("type", "PAYMENT_GATEWAY") .put("parameters", new JSONObject() .put("gateway", "finix") .put("gatewayMerchantId", "IDxxx") ); } ``` ## Step 4: Define Allowed Card Networks Now that we've requested a Finix payment token, you can set which card networks will be accepted on your site. Kotlin ```kotlin Google Pay Allowed Card Networks private val allowedCardNetworks = JSONArray(listOf( "AMEX", "DISCOVER", "INTERAC", "JCB", "MASTERCARD", "VISA")) ``` Java ```java Google Pay Allowed Card Networks private static JSONArray getAllowedCardNetworks() { return new JSONArray() .put("AMEX") .put("DISCOVER") .put("INTERAC") .put("JCB") .put("MASTERCARD") .put("VISA"); } ``` Defining `allowedCardAuthMethods` sets the authentication methods supported by your site and gateway. Kotlin ```kotlin Google Pay Allowed Card Auth Methods private val allowedCardAuthMethods = JSONArray(listOf( "PAN_ONLY", "CRYPTOGRAM_3DS")) ``` Java ```java Google Pay Allowed Card Auth Methods private static JSONArray getAllowedCardAuthMethods() { return new JSONArray() .put("PAN_ONLY") .put("CRYPTOGRAM_3DS"); } ``` For both `PAN_ONLY` and `CRYPTOGRAM_3DS` authorization methods, support for 3D Secure is dictated by the processors you integrate with in `allowedCardNetworks`. Finix accepts both `PAN_ONLY` and `CRYPTOGRAM_3DS` authorization methods. ## Step 5: Describe Allowed Payment Methods After you've defined the supported payment card networks, you need to describe your allowed payment methods. You can do this with the following steps: 1. Combine `allowedAuthMethods` and `allowedCardNetworks` to describe how your application supports the `CARD` payment method. 2. Extend the `baseCardPaymentMethod` object and describe the information you expect to be returned to your application. Include a description of the tokenized payment data. Kotlin ```kotlin Google Pay Payment Methods private fun baseCardPaymentMethod(): JSONObject = JSONObject() .put("type", "CARD") .put("parameters", JSONObject() .put("allowedAuthMethods", allowedCardAuthMethods) .put("allowedCardNetworks", allowedCardNetworks) .put("billingAddressRequired", true) .put("billingAddressParameters", JSONObject() .put("format", "FULL") ) ) private val cardPaymentMethod: JSONObject = baseCardPaymentMethod() .put("tokenizationSpecification", gatewayTokenizationSpecification) ``` Java ```java Google Pay Payment Methods private static JSONObject getBaseCardPaymentMethod() throws JSONException { return new JSONObject() .put("type", "CARD") .put("parameters", new JSONObject() .put("allowedAuthMethods", getAllowedCardAuthMethods()) .put("allowedCardNetworks", getAllowedCardNetworks()) .put("billingAddressRequired", true) .put("billingAddressParameters", new JSONObject() .put("format", "FULL") ) ); } private static JSONObject getCardPaymentMethod() throws JSONException { return getBaseCardPaymentMethod() .put("tokenizationSpecification", getGatewayTokenizationSpecification()); } ``` ## Step 6: Create a PaymentsClient Instance Create a `PaymentsClient` instance to interact with the Google Pay API. Kotlin ```kotlin PaymentsClient Instance fun createPaymentsClient(context: Context): PaymentsClient { val walletOptions = Wallet.WalletOptions.Builder() .setEnvironment(Constants.PAYMENTS_ENVIRONMENT) .build() return Wallet.getPaymentsClient(context, walletOptions) } ``` Java ```java PaymentsClient Instance public static PaymentsClient createPaymentsClient(Context context) { Wallet.WalletOptions walletOptions = new Wallet.WalletOptions.Builder().setEnvironment(Constants.PAYMENTS_ENVIRONMENT).build(); return Wallet.getPaymentsClient(context, walletOptions); } ``` ## Step 7: Check Readiness to Pay with Google Pay Now that you've described your allowed payment methods, you need to check readiness to pay with the Google Pay API. To check readiness to pay with Google Pay's API: 1. Add `allowedPaymentMethods` to the `baseRequest` object. 2. Call `isReadyToPay()` to determine if the user can make payments with the Google Pay API. Kotlin ```kotlin Google Pay Readiness Check fun isReadyToPayRequest(): JSONObject? = try { baseRequest .put("allowedPaymentMethods", JSONArray().put(baseCardPaymentMethod())) } catch (e: JSONException) { null } 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) } } } ``` Kotlin (coroutines) ```kotlin Google Pay Readiness Check private suspend fun fetchCanUseGooglePay(): Boolean { val request = IsReadyToPayRequest.fromJson(PaymentsUtil.isReadyToPayRequest().toString()) return paymentsClient.isReadyToPay(request).await() } ``` Couroutines The Tasks API lets you resolve task operations using coroutines. For more information, see [Google Pay Integration](https://developers.google.com/pay/api/android/guides/tutorial#kotlincoroutines) Java ```java Google Pay Readiness Check public static JSONObject getIsReadyToPayRequest() { try { return getBaseRequest() .put("allowedPaymentMethods", new JSONArray().put(getBaseCardPaymentMethod())); } catch (JSONException e) { return null; } } private void possiblyShowGooglePayButton() { final Optional 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 task = paymentsClient.isReadyToPay(request); task.addOnCompleteListener(this, new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { if (task.isSuccessful()) { setGooglePayAvailable(task.getResult()); } else { Log.w("isReadyToPay failed", task.getException()); } } }); } ``` ## Step 8: Add Google Pay Button Now that you've checked readiness to pay with Google Pay API, you can add a Google Pay payment button to your website. - For information about the different button types and display requirements, see [Google's Brand guidelines](https://developers.google.com/pay/api/web/guides/brand-guidelines). - To try all the different Google Pay buttons, see [Google Pay's interactive demo](https://developers.google.com/pay/api/web/guides/resources/customize). Kotlin (compose) ```kotlin Google Pay Button PayButton( modifier = Modifier .testTag("payButton") .fillMaxWidth(), onClick = onGooglePayButtonClick, allowedPaymentMethods = PaymentsUtil.allowedPaymentMethods.toString() ) ``` Jetpack Compose Element Note: To use the Jetpack Compose element, add the `com.google.pay.button:compose-pay-button` library to the list of dependencies in your Gradle build file. For more information see [Google Pay Payment Button](https://developers.google.com/pay/api/android/guides/tutorial#add-button) XML ```xml Google Pay Button ``` If you’re adding the Google Pay button via XML, be sure to initialize it in your Android activity along with other UI elements. Kotlin ```kotlin Initialize Google Pay Button override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Use view binding to access the UI elements layout = ActivityCheckoutBinding.inflate(layoutInflater) setContentView(layout.root) // Setup buttons googlePayButton = layout.googlePayButton googlePayButton.initialize( ButtonOptions.newBuilder() .setAllowedPaymentMethods(PaymentsUtil.allowedPaymentMethods.toString()).build() ) googlePayButton.setOnClickListener { requestPayment() } // Check Google Pay availability model.canUseGooglePay.observe(this, Observer(::setGooglePayAvailable)) } ``` Java ```java Initialize Google Pay Button private void initializeUi() { // Use view binding to access the UI elements ActivityCheckoutBinding layoutBinding = ActivityCheckoutBinding.inflate(getLayoutInflater()); setContentView(layoutBinding.getRoot()); // The Google Pay button is a layout file – take the root view googlePayButton = layoutBinding.googlePayButton; try { googlePayButton.initialize( ButtonOptions.newBuilder() .setAllowedPaymentMethods(PaymentsUtil.getAllowedPaymentMethods().toString()).build() ); googlePayButton.setOnClickListener(this::requestPayment); } catch (JSONException e) { // Keep Google Pay button hidden (consider logging this to your app analytics service) } } ``` ## Step 9: Create a Payment Data Request After creating a Google Pay payment button, you need to create a `PaymentDataRequest` object. The `PaymentDataRequest` takes in information about the merchant and transaction which is required to start the payment process with Google Pay. Kotlin ```kotlin paymentDataRequest private fun getTransactionInfo(price: String): JSONObject = JSONObject() .put("totalPrice", price) .put("totalPriceStatus", "FINAL") .put("countryCode", Constants.COUNTRY_CODE) .put("currencyCode", Constants.CURRENCY_CODE) private val merchantInfo: JSONObject = JSONObject().put("merchantName", "Example Merchant") ``` Java ```java paymentDataRequest private static JSONObject getTransactionInfo(String price) throws JSONException { return new JSONObject() .put("totalPrice", price) .put("totalPriceStatus", "FINAL") .put("countryCode", Constants.COUNTRY_CODE) .put("currencyCode", Constants.CURRENCY_CODE) .put("checkoutOption", "COMPLETE_IMMEDIATE_PURCHASE"); } private static JSONObject getMerchantInfo() throws JSONException { return new JSONObject().put("merchantName", "Example Merchant"); } ``` #### `getTransactionInfo` Request Arguments | Field | Type | Description | | --- | --- | --- | | `countryCode` | *string*, **required** | The ISO country code. | | `currencyCode` | *string*, **required** | The currency code of the locale. | | `totalPrice` | *string*, **required** | Total value of the transaction with an optional decimal precision of two decimal places. | | `totalPriceStatus` | *string*, **required** | The status of the total price used. Pass **FINAL** if the total price doesn't change from the amount presented to the buyer.Pass **ESTIMATED** if the total price might adjust based on the details of the response, such as sales tax collected that's based on a billing address.Pass **NOT_CURRENTLY_KNOWN** when using `totalPriceStatus` for a capability check. | #### `getMerchantInfo` Request Arguments | Field | Type | Description | | --- | --- | --- | | `merchantID` | *string*, **required** | A Google merchant identifier issued after registration with the Google Pay Business Console. Required when PaymentsClient is initialized with an environment property of **LIVE** | | `merchantName` | *string*, **required** | Pass in the name of the `Merchant` . | Strong Customer Authentication (SCA) Merchants that process transactions in the European Economic Area (EEA) or any other countries that are subject to Strong Customer Authentication (SCA) must include the `countryCode`, `totalPrice`, and `merchantName` parameters to meet SCA requirements. Assign your base request object to a new `PaymentDataRequest` JSON object. Then, add the payment methods supported by your application, such as any configuration of additional data expected in the response. Finally, add information about the transaction and the merchant who makes the request. For more information, see [Step 5 of Google Pay Integration](https://developers.google.com/pay/api/android/guides/tutorial#payment-data-request) ## Step 10: Get Buyer Identity A buyer identity is required before you can proceed with the next steps. You can either create a new buyer identity through the Finix API, or use an existing one you’ve already created. Buyer Identity Data All buyer Identity fields are optional. However, Finix recommends including basic information (name, email, address, and phone) to make payment operations easier. details summary Use an existing buyer 1. Log in to your [Finix Dashboard](https://finix.payments-dashboard.com/Login). 2. In the left sidebar, select **Data Resources** → **Identities**. 3. Search for the buyer identity you want to use. - Confirm the Role is **Buyer**. - Option to use filters to quickly narrow down results. 4. Copy the Buyer Identity (e.g. `IDjWktr7BPDGhz4amrPJZoXg` ) details summary Create a new buyer ```shell Buyer Identity Request curl -i -X POST \ -u USfdccsr1Z5iVbXDyYt7hjZZ:313636f3-fac2-45a7-bff7-a334b93e7bda \ https://finix.sandbox-payments-api.com/identities \ -H 'Content-Type: application/json' \ -H 'Finix-Version: 2022-02-01' \ -d '{ "entity": { "phone": "7145677613", "first_name": "John", "last_name": "Smith", "email": "finix_example@finix.com", "personal_address": { "city": "San Mateo", "country": "USA", "region": "CA", "line2": "Apartment 7", "line1": "741 Douglass St", "postal_code": "94114" } }, "identity_roles": [ "BUYER" ], "tags": { "key": "value" }, "type": "PERSONAL" }' ``` ```json Buyer Identity Response { "id": "IDmkDvJfxZWMEK56FDFtbozo", "created_at": "2024-08-09T09:34:36.87Z", "updated_at": "2024-08-09T09:34:36.87Z", "application": "APgPDQrLD52TYvqazjHJJchM", "entity": { "ach_max_transaction_amount": 0, "amex_mid": null, "annual_card_volume": 0, "business_address": null, "business_name": null, "business_phone": null, "business_tax_id_provided": false, "business_type": null, "default_statement_descriptor": null, "discover_mid": null, "dob": null, "doing_business_as": null, "email": "finix_example@finix.com", "first_name": "John", "has_accepted_credit_cards_previously": false, "incorporation_date": null, "last_name": "Smith", "max_transaction_amount": 0, "mcc": null, "ownership_type": null, "personal_address": { "line1": "741 Douglass St", "line2": "Apartment 7", "city": "San Mateo", "region": "CA", "postal_code": "94114", "country": "USA" }, "phone": "7145677613", "principal_percentage_ownership": null, "short_business_name": null, "tax_authority": null, "tax_id_provided": false, "title": null, "url": null }, "identity_roles": [], "tags": { "key": "value" }, "type": "PERSONAL", "_links": { "self": { "href": "https://finix.sandbox-payments-api.com/identities/IDmkDvJfxZWMEK56FDFtbozo" }, "verifications": { "href": "https://finix.sandbox-payments-api.com/identities/IDmkDvJfxZWMEK56FDFtbozo/verifications" }, "merchants": { "href": "https://finix.sandbox-payments-api.com/identities/IDmkDvJfxZWMEK56FDFtbozo/merchants" }, "settlements": { "href": "https://finix.sandbox-payments-api.com/identities/IDmkDvJfxZWMEK56FDFtbozo/settlements" }, "authorizations": { "href": "https://finix.sandbox-payments-api.com/identities/IDmkDvJfxZWMEK56FDFtbozo/authorizations" }, "transfers": { "href": "https://finix.sandbox-payments-api.com/identities/IDmkDvJfxZWMEK56FDFtbozo/transfers" }, "payment_instruments": { "href": "https://finix.sandbox-payments-api.com/identities/IDmkDvJfxZWMEK56FDFtbozo/payment_instruments" }, "associated_identities": { "href": "https://finix.sandbox-payments-api.com/identities/IDmkDvJfxZWMEK56FDFtbozo/associated_identities" }, "disputes": { "href": "https://finix.sandbox-payments-api.com/identities/IDmkDvJfxZWMEK56FDFtbozo/disputes" }, "application": { "href": "https://finix.sandbox-payments-api.com/applications/APgPDQrLD52TYvqazjHJJchM" } } } ``` ## Step 11: Create a Payment Instrument Call `loadPaymentData` using the Google Pay `PaymentsClient` object, which results in a `Task` object. Extract the payment token from the `PaymentData` result object. For more information, see [Step 6 of Google Pay Integration](https://developers.google.com/pay/api/android/guides/tutorial#initiate-payment) Kotlin ```kotlin paymentDataRequest fun getLoadPaymentDataTask(priceLabel: String): Task { val paymentDataRequestJson = PaymentsUtil.getPaymentDataRequest(priceLabel) val request = PaymentDataRequest.fromJson(paymentDataRequestJson.toString()) return paymentsClient.loadPaymentData(request) } ``` Java ```java paymentDataRequest public Task getLoadPaymentDataTask(String priceLabel) { JSONObject paymentDataRequestJson = PaymentsUtil.getPaymentDataRequest(priceLabel); if (paymentDataRequestJson == null) { return null; } PaymentDataRequest request = PaymentDataRequest.fromJson(paymentDataRequestJson.toString()); return paymentsClient.loadPaymentData(request); } ``` To process the result use one of the activity result contracts in the API. For more information, see [Step 6 of Google Pay Integration](https://developers.google.com/pay/api/android/guides/tutorial#initiate-payment) Before presenting the user with a confirmation of their purchase, extract the payment token from `PaymentData` result object, and use it in the Payment Instrument request below. You need to pass in the `third_party_token`, `name`, and billing `address` that Google Pay returns when creating a [`Payment Instrument`](/api/payment-instruments). #### Request Arguments | Field | Type | Description | | --- | --- | --- | | `identity` | *string*, **required** | ID of the `Identity` that the card should be associated with. **Source:** Buyer Identity (Step 10: Get Buyer Identity) | | `merchant_identity` | *string*, **required** | The `merchant_identity_id` used when registering the business with Apple Pay through our registration API. **Source:** Log in to Finix Dashboard → Developer → Finix Integration → Merchant Identity ID (e.g. `IDwhCCvPwCDEmiFd8Be7pDzN`) | | `name` | *string*, **required** | Full name of the registered card holder. | | `third_party_token` | *string*, **required** | Stringified token provided by Google. Required to process Google Pay transactions. | | `type` | *string*, **required** | Use **GOOGLE_PAY** for type of Payment Instrument. | | `address` | *object*, **optional** | Object containing address data. If address is not passed, fees will apply. | ```shell Payment Instrument Request curl https://finix.sandbox-payments-api.com/payment_instruments \ -H 'Content-Type: application/json' \ -H 'Finix-Version: 2022-02-01' \ -u USsRhsHYZGBPnQw8CByJyEQW:8a14c2f9-d94b-4c72-8f5c-a62908e5b30e \ -d '{ "identity": "ID78Fh8mcnnzukVzbdoyex5y", "merchant_identity": "IDwhCCvPwCDEmiFd8Be7pDzN", "name": "Finix Sandbox", "third_party_token": "{\"signature\":\"MEYCIQCYTkaEMgug7pcjzEEdbIn+R57kYO5yYc2KYj41AQQn9wIhAN1QvylvZ2XydVecfejwi2xYS9y3Y9y/MmDnRnUfNw5H\",\"intermediateSigningKey\":{\"signedKey\":\"{\\\"keyValue\\\":\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4xc3fjeM9SMTjd1TL2GQCPmgqPf2h42aM3akPh/mTUBqWEgOITruK10A02rQ+4YZOvLCpQKQZzLSAd09nctnuA\\\\u003d\\\\u003d\\\",\\\"keyExpiration\\\":\\\"1648843199734\\\"}\",\"signatures\":[\"MEQCICwCI4s5YCLu4qRCyXwSJ3qG8y3ocFtP1Mque4Uzysl8AiARoD/0qbj5W0Q2PWKpxkEnfcP+nU5kwYS8FyQ9boDTmQ\\u003d\\u003d\"]},\"protocolVersion\":\"ECv2\",\"signedMessage\":\"{\\\"encryptedMessage\\\":\\\"roD4ikTpZ7Srunq+0zUnp+eiXzcuZBfIFSuZAJu1PQLXcP0RvnGDiGKtoarNCHvn+cnXsHCzIBWXMZSJ9Aglqky9VfP5a+qsXQhf5m5AFUbT2xnihtKwageGQQK6HzyjHSXXSjvuCzeo75ToOgIUxLFASZyaZ89u3Jifqhhc2c4a0Mtlx564BxXiwcxDFdtNkOle7uAIsJzsryk7Rcwgr8ZMJJM//XpvaeE5wNmkVFHUtR2uTqPm0BvkoYkFHCTRo4NHXWpxeLjXWzKGk2ELyTK1diuCa6c9ig0jO3t8BIh1cR63UeP8Ar7u5fh8C9FPPAsgPbTGLfiaRe615e4SxASgcZ4/8uWo5mikEPFqA5s2K2mid9ncXoMNYaHUc3qzJAyxHVYSd5SRNZYXHMkEcWcjnpDx+ErYjR1sMo1LMYXfrfGyZz3M69bQLKPYFe7ChjvgFI9MnfcFTNB4HAdNKMhbZT0EKinfxxGWkT7LVbGnUuqPlHp4toCe4kpbx7fulwXTj3bAFvg/qvxxwGOS38iP0HR/f+4GF0xHspqYVbdWdIJ5iJUdpBG8Nu5P56h2GEDxXMkKSmh+qbvKWlYipNNGoeg8uHc\\\\u003d\\\",\\\"ephemeralPublicKey\\\":\\\"BMqIyb1IyXhuZ4YpWm1PiRr74i3tCwDfQqJ1P4OZ3zK4Rq16SuwgJ605fCEvlViwSQuo2Hpv+CcR+2D3+/YrLB8\\\\u003d\\\",\\\"tag\\\":\\\"5K4LlTucDK7jAThbIozYtyoxX95hRNd5cJJGfxWAxw8\\\\u003d\\\"}\"}", "type": "GOOGLE_PAY", "address": { "country": "USA", "postal_code": 12345 } }' ``` ```json Payment Instrument Response { "id": "PIf8dyFFcEGBqPhaG22hPyYs", "created_at": "2022-10-10T05:36:55.27Z", "updated_at": "2022-10-10T05:36:55.27Z", "address": { "city": null, "country": "USA", "line1": null, "line2": null, "postal_code": 12345, "region": null }, "application": "APeUfzF5qdNkBCtdgcf3333n", "created_via": "API", "currency": "USD", "enabled": true, "fingerprint": "FPRrcobjtdU98gr4sjiqYR1Qg", "identity": "ID78Fh8mcnnzukVzbdoyex5y", "instrument_type": "GOOGLE_PAY", "bin": "411111", "brand": "VISA", "card_type": "UNKNOWN", "expiration_month": 12, "expiration_year": 2027, "issuer_country": "UNKNOWN", "last_four": "1111", "name": "Finix Sandbox", "tags": {}, "type": "GOOGLE_PAY", "_links": { "self": { "href": "https://finix.sandbox-payments-api.com/payment_instruments/PIf8dyFFcEGBqPhaG22hPyYs" }, "authorizations": { "href": "https://finix.sandbox-payments-api.com/payment_instruments/PIf8dyFFcEGBqPhaG22hPyYs/authorizations" }, "transfers": { "href": "https://finix.sandbox-payments-api.com/payment_instruments/PIf8dyFFcEGBqPhaG22hPyYs/transfers" }, "verifications": { "href": "https://finix.sandbox-payments-api.com/payment_instruments/PIf8dyFFcEGBqPhaG22hPyYs/verifications" }, "application": { "href": "https://finix.sandbox-payments-api.com/applications/APeUfzF5qdNkBCtdgcf3333n" }, "identity": { "href": "https://finix.sandbox-payments-api.com/identities/ID78Fh8mcnnzukVzbdoyex5y" } } } ``` For security purposes, [Google Pay tokens](https://support.google.com/pay/merchants/answer/6345242?hl=en#) are only active for a short period of time. Due to this limited lifetime, the `third_party_token` used in the request above has expired. To test the request, use your `third_party_token` and Finix credentials. ## Step 12: Create a Payment Similar to other Finix transactions, after the `Payment Instrument` is created, you can use the instrument and create a [`transfer`](/api/transfers) or an [`authorization`](/api/authorizations/createauthorization) to process transactions. #### Sale - Set the `source` to your Buyer's Payment Instrument ID - Set the `merchant` to an `APPROVED` Merchant account - Set the `amount` in cents ```shell Example Transfer Request curl https://finix.sandbox-payments-api.com/transfers \ -H "Content-Type: application/json" \ -H 'Finix-Version: 2022-02-01' \ -u USsRhsHYZGBPnQw8CByJyEQW:8a14c2f9-d94b-4c72-8f5c-a62908e5b30e \ -d '{ "merchant": "MUeDVrf2ahuKc9Eg5TeZugvs", "currency": "USD", "amount": 662154, "source": "PIf8dyFFcEGBqPhaG22hPyYs", }' ``` ```json Example Transfer Response { "id": "TR29av3LN1TAGPbXscsup1tt", "amount": 662154, "tags": {}, "state": "SUCCEEDED", "trace_id": "34f40e87-2599-414b-874b-f472790ff521", "currency": "USD", "application": "APgPDQrLD52TYvqazjHJJchM", "source": "PImE5ZhGZJNFy14DtX8wX6f6", "destination": null, "ready_to_settle_at": null, "externally_funded": "UNKNOWN", "fee": 0, "statement_descriptor": "FNX*FINIX FLOWERS", "type": "DEBIT", "messages": [], "raw": null, "created_at": "2022-08-25T20:39:37.59Z", "updated_at": "2022-08-25T20:39:38.17Z", "idempotency_id": null, "merchant": "MUeDVrf2ahuKc9Eg5TeZugvs", "merchant_identity": "IDpYDM7J9n57q849o9E9yNrG", "subtype": "API", "failure_code": null, "failure_message": null, "additional_buyer_charges": null, "_links": { "application": { "href": "https://finix.sandbox-payments-api.com/applications/APgPDQrLD52TYvqazjHJJchM" }, "self": { "href": "https://finix.sandbox-payments-api.com/transfers/TR29av3LN1TAGPbXscsup1tt" }, "merchant_identity": { "href": "https://finix.sandbox-payments-api.com/identities/IDuqZpDw28f2KK6YuDk4jNLg" }, "payment_instruments": { "href": "https://finix.sandbox-payments-api.com/transfers/TR29av3LN1TAGPbXscsup1tt/payment_instruments" }, "reversals": { "href": "https://finix.sandbox-payments-api.com/transfers/TR29av3LN1TAGPbXscsup1tt/reversals" }, "fees": { "href": "https://finix.sandbox-payments-api.com/transfers/TR29av3LN1TAGPbXscsup1tt/fees" }, "disputes": { "href": "https://finix.sandbox-payments-api.com/transfers/TR29av3LN1TAGPbXscsup1tt/disputes" }, "source": { "href": "https://finix.sandbox-payments-api.com/payment_instruments/PIe2YvpcjvoVJ6PzoRPBK137" }, "fee_profile": { "href": "https://finix.sandbox-payments-api.com/fee_profiles/FPvCQUcnsueN3Bc3zR1qCBG8" } } } ``` #### Authorization You can create an Authorization and capture it later using two separate API calls. This approach is useful if you need to first verify the payment details and then capture a specific amount at a later time. For more details, see [Creating and Capturing an Authorization](/guides/online-payments/payment-features/auth-and-captures).