alt

Important information

Please be advised that there will be a scheduled downtime across our API network on November 05 and November 07, 2024. For more information, visit our platform status portal.:
- Scheduled maintenance on November 5, 2024
- Scheduled maintenance on November 7, 2024

Unzer

Accept Google Pay with server-side-only integration

Build your own payment form to add Google Pay payment to the checkout page.

Overview

Google Pay™ doesn’t require any input from the customer on the merchant website. The customer must be redirected to Google Pay to provide the required information to process the transaction. After that, the customer is redirected back to the merchant’s website, displaying the result of the payment.

You can see an example of Google Pay on our demo page.

Before you begin

Step 1: Create a payment type resource
server side

When creating the payment type googlepay, you need to send a request to the Unzer API. The response will contain an id, this is later referred to as typeId. You will need this typeId to perform the transaction.

The following parameters can be extracted from the Google Pay Payment Token, which is returned after the user has successfully selected the credit card.

ParameterTypeDescription
protocolVersion
(required)
string (1-4 characters)Identifies the encryption or signing scheme of the message creation. It allows the protocol to evolve over time, if required.
signature
(required)
stringVerifies that the message came from Google. It’s base64-encoded, and put together with Elliptic Curve Digital Signature Algorithm (ECDSA) by the intermediate signing key.
intermediateSigningKey.signedKey.keyExpiration
(required)
string (1-19 characters)Key Expiration from the Google Pay Token
Date and time when the intermediate key expires as UTC milliseconds since epoch. Integrators reject any expired keys.
intermediateSigningKey.signedKey.keyValue
(required)
stringKey Value from the Google Pay Token
A base64 version of the key encoded in ASN.1 type. The definition of SubjectPublicKeyInfo is in the X.509 standard.
intermediateSigningKey.signatures
(required)
Array of stringsSignatures from the Google Pay Token
Verifies that the intermediate signing key came from Google. It’s base64-encoded, and is put together with ECDSA.
signedMessage.encryptedMessage
(required)
stringA base64-encoded encrypted message that contains payment information and some additional security fields.
signedMessage.ephemeralPublicKey
(required)
stringA base64-encoded ephemeral public key that associates with the private key to encrypt the message in uncompressed point format.
signedMessage.tag
(required)
stringA base64-encoded MAC of encryptedMessage.
POST https://api.unzer.com/v1/types/googlepay/

{
	"signature": "MEYCIQDNY6f6fhBwN1H4W7WFy95TD/9OyUWU4m8aoCPlL6Nf8QIhAK21qHxe90ZX/XqfyW18Ih999OUcpjLF9pmldkImfU70",
	"intermediateSigningKey": {
		"signedKey": {
			"keyValue": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+BozvQ/G21ayTpcw/N39LhARudRyZa2obYhd39+Pr2A9muwZ3pSylUTRTxKeSWG4z8EwkfBlDefFOrXJPqYAaw==",
			"keyExpiration": "1707974138620"
		},
		"signatures": [
			"MEQCIG4WpGdYo550OeC3BCwPFwTlpvIq1ONbiwTTO7Brn4LNAiB7W5bum8xXCxrXDYD3+VDle6lKWA9qvjYDINqitD/Dfw=="
		]
	},
	"protocolVersion": "ECv2",
	"signedMessage": {
		"encryptedMessage": "ub21bnxEpzahIjwf9I3+dfmfuAjOgbgMLBWq4+ufExxs73By7MUfob0Q2u//GlsrbZ8f2Ud/jL4V8oURaG93SH4gRObOjt4LrR9e/FZ0CUlhveEp1Yn6xj1M8ZI9AFY2U+D49Xn8XUDW8V0Gqbm1slhiOCfIbSRsyHj7c3i2kAqo2HRyBWOrIv9ExV9ReuEMkNGhv93kvL+jmbb7Z6yunM872AzyWcr9+TUAWZCwSrnheQQpPbepZX7Ed1JlaJlDxcrSzDHrm4RWr/MhmyKzHl4lb7LNea39qMUDuBmEKBpl8L5lT65pDOj42NUPfhipSX4jD40Az4F2XGuD71MnvhTnJqizYpt7TDHwBZuUXaG2kEBmkxddpJ7WBQZA0DIw4O56kj4blbHF05tfDP1rDQMBN4ayPnLUzYjaan/ibspaVAgm7QyChgpzQMuo/vkwtwkeIWVUrxCHoHGUQfGsUb5OCLSH1haSoKtIdfxK393A6djbC3qh5bguJy6FqXenYl7peCuY+N+5AE7FLeCWHjXcOQAOKo6tsmUbljmfZg7udBiwhaTh/UuvxLhIzNpLWZOfbByWBc6QCBN1AFqJF2NFnG2cS+LiaTWYQ9vCYg==",
		"ephemeralPublicKey": "BHlK/K1NEUP9MY6Z/yPEucFuL5aGm058r2zxHCVRGSEKpW3RSKcUPYhQvnSJjxDd1F73Jc9dJLJRl5RjyxH9F90=",
		"tag": "ah5e4DDE2o08PeSV6eCrsuyFNUSbak/XESIiCKk6EWU="
	}
}
$unzer = new Unzer('s-priv-xxxxxxxxxx');

$intermediateSigningKey = (new IntermediateSigningKey())
    ->setSignatures(['MEQCIG4WpGdYo550OeC3BCwPFwTlpvIq1ONbiwTTO7Brn4LNAiB7W5bum8xXCxrXDYD3+VDle6lKWA9qvjYDINqitD/Dfw=='])
    ->setSignedKey(new SignedKey(
            '1707974138620',
            'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+BozvQ/G21ayTpcw/N39LhARudRyZa2obYhd39+Pr2A9muwZ3pSylUTRTxKeSWG4z8EwkfBlDefFOrXJPqYAaw=='
        )
    );

$googlepay = new Googlepay(
    'ECv2',
    'MEYCIQDNY6f6fhBwN1H4W7WFy95TD/9OyUWU4m8aoCPlL6Nf8QIhAK21qHxe90ZX/XqfyW18Ih999OUcpjLF9pmldkImfU70',
    $intermediateSigningKey,
    new SignedMessage(
        'ah5e4DDE2o08PeSV6eCrsuyFNUSbak/XESIiCKk6EWU=',
        'BHlK/K1NEUP9MY6Z/yPEucFuL5aGm058r2zxHCVRGSEKpW3RSKcUPYhQvnSJjxDd1F73Jc9dJLJRl5RjyxH9F90=',
        'ub21bnxEpzahIjwf9I3+dfmfuAjOgbgMLBWq4+ufExxs73By7MUfob0Q2u//GlsrbZ8f2Ud/jL4V8oURaG93SH4gRObOjt4LrR9e/FZ0CUlhveEp1Yn6xj1M8ZI9AFY2U+D49Xn8XUDW8V0Gqbm1slhiOCfIbSRsyHj7c3i2kAqo2HRyBWOrIv9ExV9ReuEMkNGhv93kvL+jmbb7Z6yunM872AzyWcr9+TUAWZCwSrnheQQpPbepZX7Ed1JlaJlDxcrSzDHrm4RWr/MhmyKzHl4lb7LNea39qMUDuBmEKBpl8L5lT65pDOj42NUPfhipSX4jD40Az4F2XGuD71MnvhTnJqizYpt7TDHwBZuUXaG2kEBmkxddpJ7WBQZA0DIw4O56kj4blbHF05tfDP1rDQMBN4ayPnLUzYjaan/ibspaVAgm7QyChgpzQMuo/vkwtwkeIWVUrxCHoHGUQfGsUb5OCLSH1haSoKtIdfxK393A6djbC3qh5bguJy6FqXenYl7peCuY+N+5AE7FLeCWHjXcOQAOKo6tsmUbljmfZg7udBiwhaTh/UuvxLhIzNpLWZOfbByWBc6QCBN1AFqJF2NFnG2cS+LiaTWYQ9vCYg=='
    )
);

$unzer->createPaymentType($googlepay);
Unzer unzer = new Unzer("s-priv-xxxxxxxxxx");

IntermediateSigningKey intermediateSigningKey = new IntermediateSigningKey()
            .setSignedKey(new SignedKey()
                .setKeyExpiration("1707974138620")
                .setKeyValue("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+BozvQ/G21ayTpcw/N39LhARudRyZa2obYhd39+Pr2A9muwZ3pSylUTRTxKeSWG4z8EwkfBlDefFOrXJPqYAaw==")
            )
            .setSignatures(Arrays.asList("MEQCIG4WpGdYo550OeC3BCwPFwTlpvIq1ONbiwTTO7Brn4LNAiB7W5bum8xXCxrXDYD3+VDle6lKWA9qvjYDINqitD/Dfw=="));

GooglePay googlepayTypeRequest = new GooglePay()
    .setSignature("MEYCIQDNY6f6fhBwN1H4W7WFy95TD/9OyUWU4m8aoCPlL6Nf8QIhAK21qHxe90ZX/XqfyW18Ih999OUcpjLF9pmldkImfU70")
    .setIntermediateSigningKey(intermediateSigningKey)
    .setProtocolVersion("ECv2")
    .setSignedMessage(new SignedMessage()
        .setTag("ah5e4DDE2o08PeSV6eCrsuyFNUSbak/XESIiCKk6EWU=")
        .setEncryptedMessage("ub21bnxEpzahIjwf9I3+dfmfuAjOgbgMLBWq4+ufExxs73By7MUfob0Q2u//GlsrbZ8f2Ud/jL4V8oURaG93SH4gRObOjt4LrR9e/FZ0CUlhveEp1Yn6xj1M8ZI9AFY2U+D49Xn8XUDW8V0Gqbm1slhiOCfIbSRsyHj7c3i2kAqo2HRyBWOrIv9ExV9ReuEMkNGhv93kvL+jmbb7Z6yunM872AzyWcr9+TUAWZCwSrnheQQpPbepZX7Ed1JlaJlDxcrSzDHrm4RWr/MhmyKzHl4lb7LNea39qMUDuBmEKBpl8L5lT65pDOj42NUPfhipSX4jD40Az4F2XGuD71MnvhTnJqizYpt7TDHwBZuUXaG2kEBmkxddpJ7WBQZA0DIw4O56kj4blbHF05tfDP1rDQMBN4ayPnLUzYjaan/ibspaVAgm7QyChgpzQMuo/vkwtwkeIWVUrxCHoHGUQfGsUb5OCLSH1haSoKtIdfxK393A6djbC3qh5bguJy6FqXenYl7peCuY+N+5AE7FLeCWHjXcOQAOKo6tsmUbljmfZg7udBiwhaTh/UuvxLhIzNpLWZOfbByWBc6QCBN1AFqJF2NFnG2cS+LiaTWYQ9vCYg==")
        .setEphemeralPublicKey("BHlK/K1NEUP9MY6Z/yPEucFuL5aGm058r2zxHCVRGSEKpW3RSKcUPYhQvnSJjxDd1F73Jc9dJLJRl5RjyxH9F90=")
    );

GooglePay googlepay = unzer.createPaymentType(googlepayTypeRequest);

The response looks similar to the following example:

{
	"id" : "s-gop-p6gwgiuvjigm",
	"method" : "googlepay",
	"recurring" : false,
	"number" : "555555******4444",
	"brand" : "MASTER",
	"email" : "",
	"geoLocation" : {
	  "clientIp" : "127.0.0.1",
	  "countryIsoA2" : "DE"
	},
	"expiryDate" : "12/2026",
	"processing" : {
	  "uniqueId" : "31HA07BC8127F6AE26D43EA0DA88E93B",
	  "shortId" : "5718.2865.4969",
	  "traceId" : "5cb559ad6fcf8e39273ebda79b09418f"
	}
  }

For a full description of Google Pay payment type creation, check the API reference.

Step 2: Make a payment
server side

To make a payment, you need a customer, a basket (optional), and a paymentType resource.

Create the customer resource

This step is only applicable if you didn’t create a customer resource on the client side.

B2C customer creation

For B2C transactions, create a customer as described in the example request. To learn more about the customer resource, see the API reference.

POST https://api.unzer.com/v1/customers
{
  "salutation": "mr",
  "firstname": "Rainer",
  "lastname": "Zufall",  
  "birthDate": "1980-06-22",
  "email": "rainer.zufall@domain.de",
  "language": "de",
  "phone": "+49 152 987654321",
  "billingAddress": {
    "name": "Rainer Zufall",
    "street": "Unzerstraße 18",
    "zip": "22767",
    "city": "Hamburg",
    "country": "DE"
  },
  "shippingAddress": {
    "name": "Rainer Zufall",
    "street": "Unzerstraße 18",
    "zip": "22767",
    "city": "Hamburg",
    "country": "DE",
    "shippingType": "equals-billing"
  }
}
$address = (new Address())
    ->setName('Rainer Zufall')
    ->setStreet('Unzerstraße 18')
    ->setZip('22767')
    ->setCity('Hamburg')
    ->setCountry('DE');

$customer = (new Customer())
    ->setFirstname('Rainer')
    ->setLastname('Zufall')
    ->setSalutation(Salutations::MR)
    ->setCompany('Unzer GmbH')
    ->setBirthDate('1972-12-24')
    ->setEmail('rainer.zufall@domain.de')
    ->setLanguage("de")
    ->setPhone('+49 152 987654321')
    ->setBillingAddress($address)
    ->setShippingAddress($address);

$unzer = new Unzer('s-priv-xxxxxxxxxx');
$unzer->createCustomer($customer);
Unzer unzer = new Unzer("s-priv-xxxxxxxxxx");

Address address = new Address()
        .setName('Rainer Zufall')
        .setStreet('Unzerstraße 18')
        .setZip('22767')
        .setCity('Hamburg')
        setCountry('DE');
        
Customer customer = new Customer("John", "Doe")
        .setSalutation(Salutations::MR)
        .setCompany('Unzer GmbH')
        .setBirthDate('1972-12-24')
        .setEmail('rainer.zufall@domain.de')
        .setLanguage("de")
        .setPhone('+49 152 987654321')
        .setBillingAddress(address)
        .setShippingAddress(address);

unzer.createCustomer(customer);

The response looks similar to the following example:

{
    "id": "s-cst-b7e502fcbb10"
}

For a full description of customer resource, refer to the relevant server-side-integration documentation page: Manage customer (direct API calls).

icon
Both B2C and B2B customer types are supported.

Create a basket resource (Optional)

The basket resource stores information about the purchased products, used vouchers, and the shipment costs.

For a full description of baskets resource, refer to the relevant server-side-integration documentation page: Manage baskets (v2).

POST https://api.unzer.com/v2/baskets
{
    "totalValueGross": "105.95",
    "currencyCode": "EUR",
    "basketItems": [
        {
            "type": "goods",
            "basketItemReferenceId": "SKU-1783746",
            "title": "Jacket Fleece size M",
            "quantity": 1,
            "amountPerUnitGross": 100,
            "vat": "19"
        },
        {
            "type": "shipment",
            "basketItemReferenceId": "express-shipping",
            "title": "Shipment fee",
            "quantity": 1,                        
            "amountPerUnitGross": 5.95,
            "vat": "19"
        }
    ]
}
$unzer = new Unzer('s-priv-xxxxxxxxxx');

$basketItem1 = (new BasketItem())
    ->setBasketItemReferenceId('Item-d030efbd4963')
    ->setQuantity(10)
    ->setUnit('m')
    ->setAmountPerUnitGross(20.00)
    ->setAmountDiscountPerUnitGross(1.00)
    ->setVat(19.0)
    ->setTitle('SDM 6 CABLE')
    ->setSubTitle('This is brand new Mid 2019 version')
    ->setImageUrl('https://a.storyblok.com/f/91629/x/1ba8deb8cc/unzer_primarylogo__white_rgb.svg')
    ->setType(BasketItemTypes::GOODS);

$basketItem2 = (new UnzerSDK\Resources\EmbeddedResources\BasketItem())
    ->setTitle('Shipment fee')
    ->setBasketItemReferenceId('express-shipping')
    ->setQuantity(1)
    ->setAmountPerUnitGross(5.95)
    ->setVat(19.0)
    ->setType(UnzerSDK\Constants\BasketItemTypes::SHIPMENT);

$basket = (new Basket())
    ->setTotalValueGross(195.95)
    ->setCurrencyCode('EUR')
    ->setOrderId('Order-12345')
    ->setNote('Test Basket')
    ->addBasketItem($basketItem1)
    ->addBasketItem($basketItem2);

$unzer->createBasket($basket);
BasketItem basketItem1 = new BasketItem()
        .setBasketItemReferenceId("Item-d030efbd4963")
        .setQuantity(BigDecimal.valueOf(10))
        .setUnit("m")
        .setAmountPerUnitGross(BigDecimal.valueOf(20.00))
        .setAmountDiscountPerUnitGross(BigDecimal.valueOf(1.00))
        .setVat(BigDecimal.valueOf(19.0))
        .setTitle("SDM 6 CABLE")
        .setSubTitle("This is brand new Mid 2019 version")
        .setImageUrl(new URL("https://a.storyblok.com/f/91629/x/1ba8deb8cc/unzer_primarylogo__white_rgb.svg"))
        .setType(BasketItem.Type.GOODS);

BasketItem basketItem2 = (new BasketItem())
    .setBasketItemReferenceId("express-shipping")
    .setQuantity(1)
    .setAmountPerUnitGross(BigDecimal.valueOf(5.95))
    .setVat(BigDecimal.valueOf(19.0))
    .setTitle("Shipment fee")
    .setType(BasketItem.Type.GOODS);

Basket basket  = new Basket()
    .setTotalValueGross(BigDecimal.valueOf(195.95))
    .setCurrencyCode(Currency.getInstance("EUR"))
    .setOrderId("Order-12345")
    .setNote("Test Basket")
    .addBasketItem(basketItem1)
    .addBasketItem(basketItem2);

Unzer unzer = new Unzer("s-priv-xxxxxxxxxx");
unzer.createBasket(basket);

The response looks similar to the following example:

{
    "id": "s-bsk-7e772dd4266b"
}

For a full description of basket resource, refer to the relevant server-side-integration documentation page: Direct API integration.

Option 1: Charge the card directly

Make a charge transaction with the googlepay resource that you created in the front end. With a successful charge transaction, money is transferred from the customer to you (merchant) and a payment resource is created.

POST https://api.unzer.com/v1/payments/charges
   
Body:
{
  "amount" : "105.95",
  "currency": "EUR",
  "returnUrl": "https://www.my-shop-url.de/returnhandler",
  "resources" : {
    "typeId" : "s-gop-p6gwgiuvjigm",
    "basketId": "s-bsk-7e772dd4266b",
    "customerId": "s-cst-b7e502fcbb10"
  }
}
$unzer     = new UnzerSDK\Unzer('s-priv-xxxxxxxxxx');

$charge = new Charge(105.95, 'EUR', 'https://www.my-shop-url.de/returnhandler');
$typeId = 's-gop-3qujdbdjas5w';

$unzer->performCharge($charge, $typeId);
Unzer unzer = new Unzer("s-priv-xxxxxxxxxx");

Charge charge = (Charge) new Charge()
        .setAmount(BigDecimal.valueOf(105.95))
        .setCurrency(Currency.getInstance("EUR"))
        .setTypeId("s-gop-zex7c9iibpek")
        .setReturnUrl(unsafeUrl("https://www.my-shop-url.de/returnhandler");

unzer.charge(charge);

The response looks similar to the following example:

{
    "id": "s-chg-1",
    "isSuccess": false,
    "isPending": true,
    "isError": false,
    "redirectUrl": "https://payment.unzer.com/v1/redirect/crd/s-sGYdGywWpxzW",
    "message": {
        "code": "COR.000.100.112",
        "merchant": "Request successfully processed in 'Merchant in Connector Test Mode'",
        "customer": "Your payments have been successfully processed in sandbox mode."
    },
    "amount": "105.9500",
    "currency": "EUR",
    "returnUrl": "https://www.my-shop-url.de/returnhandler",
    "date": "2021-05-10 00:51:03",
    "resources": {
        "paymentId": "s-pay-131937",
        "traceId": "70ddf3152a798c554d9751a6d77812ae",
        "typeId": "s-gop-p6gwgiuvjigm",
        "basketId": "s-bsk-7e772dd4266b",
        "customerId": "s-cst-b7e502fcbb10"
        
    },
    "paymentReference": "",
    "processing": {
        "uniqueId": "31HA07BC8157BD2BC04D483EFA914465",
        "shortId": "4845.3426.1987",
        "traceId": "70ddf3152a798c554d9751a6d77812ae"
    }
}

For a full description of the charge transaction, refer to the relevant server-side integration documentation page: Charge a payment (direct API calls), Charge a payment (PHP SDK), Charge a payment (Java SDK).

Option 2: Authorize and then charge the card

To authorize an amount, make an authorize transaction with the googlepay resource that you created in the frontend. With a successful authorize transaction, money is reserved on the customer account and a payment resource is created.

POST https://api.unzer.com/v1/payments/authorize


 Body:
{
  "amount" : "105.95",
  "currency": "EUR",
  "returnUrl": "https://www.my-shop-url.de/returnhandler",
  "resources" : {
    "typeId" : "s-gop-p6gwgiuvjigm",
    "basketId": "s-bsk-7e772dd4266b",
    "customerId": "s-cst-b7e502fcbb10"
  }
}
$unzer     = new UnzerSDK\Unzer('s-priv-xxxxxxxxxx');

$authorization = (new Authorization(105.95, 'EUR', 'https://www.my-shop-url.de/returnhandler'));
$typeId = 's-gop-3qujdbdjas5w';

$unzer->performAuthorization($authorization, $typeId);
Unzer unzer = new Unzer("s-priv-xxxxxxxxxx");
    
Authorization authorization = (new Authorization())
        .setAmount(BigDecimal.valueOf(105.95))
        .setCurrency(Currency.getInstance("EUR"))
        .setTypeId("s-gop-zex7c9iibpek")
        .setReturnUrl(unsafeUrl("https://www.my-shop-url.de/returnhandler");

unzer.authorize(authorization);

The response looks similar to the following example:

{
    "id": "s-aut-1",
    "isSuccess": true,
    "isPending": false,
    "isError": false,
    "card3ds": false,
    "redirectUrl": "",
    "message": {
        "code": "COR.000.100.112",
        "merchant": "Request successfully processed in 'Merchant in Connector Test Mode'",
        "customer": "Your payments have been successfully processed in sandbox mode."
    },
    "amount": "105.9500",
    "currency": "EUR",
    "returnUrl": "https://www.my-shop-url.de/returnhandler",
    "date": "2021-06-04 11:19:10",
    "resources": {
        "customerId": "s-cst-b7e502fcbb10",
        "paymentId": "s-pay-8435",
        "basketId": "s-bsk-7e772dd4266b",
        "traceId": "8ee5c53960f8b39839b70799fe224d84",
        "typeId": "s-gop-p6gwgiuvjigm"
    },
    "paymentReference": "",
    "processing": {
        "uniqueId": "31HA07BC8198C2F9107E0E3536444655",
        "shortId": "4867.3194.9885",
        "traceId": "8ee5c43960f8b39839b70799fe224d84"
    }
}

For a full description of the authorize transaction, see the relevant server-side-integration documentation page: Authorize a payment (direct API calls), Authorize a payment (PHP SDK), Authorize a payment (Java SDK).

Charge the authorization

Because the customer already accepted the payment with the authorize transaction, you can now charge the payment to transfer the money.

POST https://api.unzer.com/v1/payments/s-pay-8435/charges/
   
Body:
{
    "amount": "105.95",
}
$unzer = new Unzer('s-priv-xxxxxxxxx');
$charge = $unzer->performChargeOnPayment('s-pay-1', new Charge());
Unzer unzer = new Unzer("s-priv-xxxxxxxxxx");
Charge charge = unzer.chargeAuthorization("s-pay-1");

The response looks similar to the following example:

{
    "id": "s-chg-1",
    "isSuccess": true,
    "isPending": false,
    "isError": false,
    "card3ds": false,
    "redirectUrl": "",
    "message": {
        "code": "COR.000.100.112",
        "merchant": "Request successfully processed in 'Merchant in Connector Test Mode'",
        "customer": "Your payments have been successfully processed in sandbox mode."
    },
    "amount": "105.9500",
    "currency": "EUR",
    "date": "2021-06-04 11:19:10",
    "resources": {
        "customerId": "s-cst-b7e502fcbb10",
        "paymentId": "s-pay-8435",
        "basketId": "s-bsk-7e772dd4266b",
        "traceId": "8ee5c53960f8b39839b70799fe224d84",
        "typeId": "s-gop-p6gwgiuvjigm"
    },
    "paymentReference": "",
    "processing": {
        "uniqueId": "31HA07BC8198C2F9107E0E3536444655",
        "shortId": "4867.3194.9885",
        "traceId": "8ee5c43960f8b39839b70799fe224d84"
    }
}

Step 3: Check status of the payment
server side

Once the customer is redirected to the returnUrl, you can fetch the payment details from the API, by using the resources.paymentId from the charge response above to handle the payment according to its status. If the status of the payment is completed, the payment process has been finished successfully and can be considered as paid. Check all possible payment states here.

GET https://api.unzer.com/v1/payments/{payment_ID}

{
    "id": "s-pay-8435",
    "state": {
        "id": 1,
        "name": "completed"
    },
    "amount": {
        "total": "105.9500",
        "charged": "105.9500",
        "canceled": "0.0000",
        "remaining": "0.0000"
    },
    "currency": "EUR",
    "orderId": "",
    "invoiceId": "",
    "resources": {
        "customerId": "s-cst-b7e502fcbb10",
        "paymentId": "s-pay-8435",
        "basketId": "s-bsk-7e772dd4266b",
        "metadataId": "",
        "payPageId": "",
        "traceId": "70ddf3152a798c554d9751a6d77812ae",
        "typeId": "s-gop-p6gwgiuvjigm"
    },
    "transactions": [
        {
            "date": "2021-05-10 00:51:03",
            "type": "charge",
            "status": "success",
            "url": "https://api.unzer.com/v1/payments/s-pay-131937/charges/s-chg-1",
            "amount": "105.9500"
        }
    ]
}

Step 4: Display the payment result
client side

Use the information from the Check status of the payment step to display the payment result to your customer.
This can be the success or error page of your shop. If something went wrong, you can use the client message from the API response and show it to the customer.

Manage payment
server side

For more details on managing Google Pay payments, see Manage Google Pay payments.

Notifications

We recommend subscribing to the payment event to receive notifications about any changes to the payment resource. As soon as the event is triggered you should fetch the payment and update the order status in your shop according to its status.

  {
    "event":"payment.pending",
    "publicKey":"s-pub-xxxxxxxxxx",
    "retrieveUrl":"https://api.unzer.com/v1/payments/s-pay-774",
    "paymentId":"s-pay-774"
  }

For more details on implementing webhooks to receive notifications, see Notifications page.

Error handling

All requests to the API can result in an error that should be handled. Refer to the Error handling guide to learn more about Unzer API (and other) errors and handling them.

Test & go live

You should always test your integration before going live. First perform test transactions using test data. Next, check against Integration checklist and Go-live checklist to make sure the integration is complete and you’re ready to go live.

See also