1.) Account configuration
Step 1: Register an account
Create your free payever account here, or login in case you already have one.
Step 2: Configure payment options
In order to configure your payment options, first open the Checkout app. To do this, either click on the Checkout symbol under Business Apps or click on the Manage or Open button on the Checkout section.
You can find the payment methods tab in the navigation bar on the left.
Then click on + Add.
Now a list of different payment methods appears, from which you can select as needed. To do this, click on install.
Once you have installed the payment channel, click on Open and a new page will open, the structure of which will vary depending on the payment method chosen.
With the payment methods credit card, direct debit, Sofortüberweisung and Paypal just click the Connect button and you will be forwarded to the respective payment provider. There you connect your existing account or create a new one.
For the payment methods Installments, invoice, Factoring and Direct Bank Transfer you have to enter the access data that you have received from Santander and then click on Connect (if you have not been in touch with Santander before, please contact support@payever.de).
Regardless of the payment method, please make sure that you always enter your access data in the Default tab.
After you have connected the payment methods, you can make changes to the settings of the specific payment method. Please refer to our documentation for the specific payment method for more information, which you can find here.
Step 3: Configure channels
Select the Channels tab in the Checkout App.
Click + Add.
Select Commercetools from the list that now appears and click on Install.
Now you need to click Open so that you can generate the API keys in the next step.
Select API keys and click on + Add. Enter a name of your choice and click on Generate. Afterwards, click on the plus icon (+) and you see the credentials that you have to insert into the added connection that you use for your online business (i.e., Client Id, Client secret, Business UUID). Please copy these to your clipboard.
Select Credentials and click on Add Connection. Enter a name of your choice and fill out your Commercetools Project Key, Client Id and Secret. The copied Client Id, Secret and Business UUID from the previous step, can be inserted in the payever related fields. Choose your callback URLs to decide the customer landing pages for specific payment scenarios and select when to create an order Commercetools. Afterwards, click on Connect and you see your added connection.
2.) Integration guide
In order to use the payever gateway integration with commercetools, please follow this integration guide to make sure your implementation and process works as needed.
Terms used in this guide:
- Shopper - a person that's using the shop
- Browser - frontend part of the checkout UI (webshop)
- Merchant server - backend part of the checkout
How it works:
- Step 1: Execute required checkout validations.
- Step 2: Create the commercetools payment object.
-
Step 3 - Optional: Set
getPaymentMethodsRequestcustom field to commercetools payment to get the list of payment methods available for the checkout. - Step 4: Create a payever payment.
- Step 5: Shipping goods
- Step 6: Refund a payment
- Step 7: Cancel a payment
-
Step 8: Subscription
Step 1: commercetools checkout validations
The merchant server should execute the following validations:
- On each checkout step [validate cart state](#validate-cart-state)
- Before starting a new payment process make sure there are no paid payments on the cart already:
- Recalculate cart
- Validate payment
- Validate payment transaction
If all the above validations passed then the order can be created right away and the order confirmation page shown.
Otherwise, the shopper might continue with further payment steps.
Validate cart state - Check if current cart has been ordered already (`Cart.cartState = Ordered`).
In this case, load order by ordered cart ID and show order confirmation page.
This might happen if the cart has been already ordered in a different tab (edge case)
or by an optional asynchronous process like commercetools-payment-to-order-processor job.
Recalculate Cart - Execute cart recalculate to ensure:
- Cart totals are always up-to-date
- Time-limited discounts are eventually removed from the cart (discounts are validated on re-calculate and order creation only).
Validate Payment - There must be at least one commercetools payment object of type payever (Payment.paymentMethodInfo.paymentInterface = ctp-payever-integration).
Validate Payment Transaction - Cart's payment counts as successful if there is at least one payment object
with successful transaction state (Payment.Transaction.state=Success)
and transaction type Authorization or Charge.
Step 2: Create a commercetools payment
Before the actual payment process, commercetools payment resource needs to be created by the merchant server.
In the commercetools platform, payment represents just a container of the current state of receiving and/or refunding money.
The actual financial process is performed behind the scenes by the extension module which processes commercetools payment payload supplied by the merchant server and exchanges it with payever API.
The commercetools payment does not contain by default all the required payever specific fields, so those have to be set as custom fields via a payment method-specific payment type.
| Field name | Value |
| amountPlanned | How much money this payment intends to receive from the customer. The value usually matches the cart or order gross total. |
| paymentMethodInfo.paymentInterface | ctp-payever-integration |
| custom.type.key | ctp-payever-integration-payment-type |
| custom.fields.payeverBusinessUuid | payever Business UUID as a custom field called payeverBusinessUuid. |
| custom.fields.commercetoolsProjectKey | commercetools project key as a custom field called commercetoolsProjectKey |
In case of the absence of the required fields above, payment creation will be rejected.
Here's an example of how you would create a commercetools payment draft from scratch:
{
"amountPlanned": {
"currencyCode": "EUR",
"centAmount": 10000
},
"paymentMethodInfo": {
"paymentInterface": "ctp-payever-integration"
},
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-payment-type"
},
"fields": {
"payeverBusinessUuid": "YOUR_PAYEVER_BUSINESS_UUID",
"commercetoolsProjectKey": "YOUR_COMMERCETOOLS_PROJECT_KEY"
}
}
}
Create a payment with commercetools API.
After successful payment creation always add it to the appropriate cart.
Step 3 (optional): Get available payment methods
When your shopper is ready to pay, you may request through the integration a list of the available payment methods based on the transaction context (like amount, country, and currency).
This step is optional but payever recommends to use it so that merchant server can always serve latest list of payment methods. During checkout you might also want to cache the list instead of requesting it every time a customer attempts to pay.
To get available payment methods via our integration, you need to set the `getPaymentMethodsRequest` custom field to your existing commercetools payment or create a payment right away with the custom fieldset.
If you don't have a payment object, check creating a new commercetools payment and set getPaymentMethodsRequest custom field together with other required fields.
This is an example of the getPaymentMethodsRequest custom field value for a German shopper and payment amount of 10 EUR:
{
"countryCode": "DE",
"currencyCode": "EUR",
"amount": 10000
}Refer payever List Payment Options request to check the response code example.
This is an example of the commercetools payment representation with getPaymentMethodsRequest:
{
"amountPlanned": {
"currencyCode": "EUR",
"centAmount": 10000
},
"paymentMethodInfo": {
"paymentInterface": "ctp-payever-integration"
},
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-payment-type"
},
"fields": {
"payeverBusinessUuid": "YOUR_PAYEVER_BUSINESS_UUID",
"commercetoolsProjectKey": "YOUR_COMMERCETOOLS_PROJECT_KEY"
"getPaymentMethodsRequest": "{\"countryCode\":\"DE\", \"currencyCode\":\"EUR\", \"amount\": 100}"
}
}
}
Pass the getPaymentMethodsResponse custom field value to your front end. You might use this in the next step to show which payment methods are available for the shopper.
The commercetools payment representation example with response:
{
"amountPlanned": {
"currencyCode": "EUR",
"centAmount": 10000
},
"paymentMethodInfo": {
"paymentInterface": "ctp-payever-integration"
},
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-payment-type"
},
"fields": {
"payeverBusinessUuid": "YOUR_PAYEVER_BUSINESS_UUID",
"commercetoolsProjectKey": "YOUR_COMMERCETOOLS_PROJECT_KEY",
"getPaymentMethodsRequest": "{\"countryCode\":\"DE\", \"currencyCode\":\"EUR\", \"amount\": 100}"
"getPaymentMethodsResponse": "[{\"name\":\"Credit Card\",\"fixed_fee\":0.25,\"variable_fee\":2.9,\"accept_fee\":true,\"payment_method\":\"stripe\",\"description_offer\":\"Accept all Credit Card payments with Stripe.\",\"description_fee\":\"<p>Credit card fees are only 2.9% + 0.25\u20ac per successful transaction.<\/p>\",\"status\":\"active\",\"is_redirect_method\":false,\"merchant_allowed_countries\":[],\"instruction_text\":\"Simply connect your Stripe and payever accounts, or create a new Stripe account.\",\"thumbnail1\":\"https:\/\/payeverproduction.blob.core.windows.net\/miscellaneous\/456863ab-2a66-4552-bfd7-828dcba8b15d-CARDS.png\",\"thumbnail2\":\"https:\/\/payeverproduction.blob.core.windows.net\/miscellaneous\/456863ab-2a66-4552-bfd7-828dcba8b15d-CARDS.png\",\"options\":{\"currencies\":[\"AUD\",\"CAD\",\"CZK\"],\"countries\":[\"DE\",\"BE\",\"FR\"]},\"max\":100000,\"min\":0.5},{\"name\":\"Stripe DirectDebit\",\"fixed_fee\":0.25,\"variable_fee\":2.9,\"accept_fee\":true,\"payment_method\":\"stripe_directdebit\",\"description_offer\":\"Accept SEPA Direct Debit Payments with Stripe.\",\"description_fee\":\"<p>DirectDebit fees are only 2.9% + 0.25\u20ac per successful transaction.<\/p>\",\"status\":\"active\",\"is_redirect_method\":false,\"merchant_allowed_countries\":[],\"instruction_text\":\"Simply connect your Stripe and payever accounts, or create a new Stripe account.\",\"thumbnail1\":\"https:\/\/payeverproduction.blob.core.windows.net\/miscellaneous\/5a8aa19a-fd16-47df-8fdc-53e9d62af2d2-EC.png\",\"thumbnail2\":\"https:\/\/payeverproduction.blob.core.windows.net\/miscellaneous\/5a8aa19a-fd16-47df-8fdc-53e9d62af2d2-EC.png\",\"options\":{\"currencies\":[\"AUD\",\"CAD\",\"CZK\"],\"countries\":[\"DE\",\"BE\",\"FR\"]},\"max\":100000,\"min\":0}]"
}
}
}
Request/response between payever and extension module are stored in interfaceInteraction field of the payment with type refund.
The commercetools payment representation after a successful refund:
Step 4: Create a payever payment
When a shopper selects a payment method, payever will return a redirect_url that the merchant server needs to either redirect the customer to or open within an iframe on his page, in order for the customer to finalise his payment there.
For details, consult the payever API V1 documentation and payever API V2 documentation
To create payment via our integration, you need to set the `createPaymentRequest` custom field to existing commercetools payment with parameters.
If you don't have a payment object, check creating a new commercetools payment and set createPaymentRequest custom field together with other required fields.
Preconditions - payment.amountPlanned can not be changed if there is a createPayment interface interaction present in the commercetools payment object. The amount value in createPaymentRequest custom field must have the same value as payment.amountPlanned. This ensures eventual payment amount manipulations (i.e.: when my-payments are used) for already initiated payment.
Important - In this integration document our payever payment request examples are trimmed to minimum.
Please find all the possible parameters in the payever API V1 Documentation and payever API V2 documentation.
Here's an example of the `createPaymentRequest` custom field value for Santander Invoice DE payment:
{
"amount": 100,
"fee": 0,
"order_id": "000001",
"currency": "EUR",
"payment_method": "santander_invoice_de",
"first_name": "Stub",
"last_name": "Accepted",
"country": "DE",
"city": "Berlin",
"street": "Test 1",
"email": "test@test.de",
"phone": "98749874",
"zip": "12345"
}
An example of payment setCustomField action with the generated component data above.
{
"version": "PAYMENT_VERSION",
"actions": [
{
"action": "setCustomField",
"name": "createPaymentRequest",
"value": "{\"amount\": 100, \"fee\": 0, \"order_id\": \"000001\", \"currency\": \"EUR\", \"payment_method\": \"santander_invoice_de\", \"first_name\" : \"Stub\", \"last_name\" : \"Accepted\", \"country\" : \"DE\", \"city\" : \"berlin\", \"street\" : \"Test 1\" , \"email\" : \"test@test.de\", \"phone\" : \"98749874\", \"zip\": \"12345\" }"
}
]
}
The commercetools payment representation example with createPaymentRequest request.
{
"amountPlanned": {
"currencyCode": "EUR",
"centAmount": 10000
},
"paymentMethodInfo": {
"paymentInterface": "ctp-payever-integration"
},
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-payment-type"
},
"fields": {
"payeverBusinessUuid": "YOUR_PAYEVER_BUSINESS_UUID",
"commercetoolsProjectKey": "YOUR_COMMERCETOOLS_PROJECT_KEY",
"createPaymentRequest": "{\"amount\": 100, \"fee\": 0, \"order_id\": \"000001\", \"currency\": \"EUR\", \"payment_method\": \"santander_invoice_de\", \"first_name\" : \"Stub\", \"last_name\" : \"Accepted\", \"country\" : \"DE\", \"city\" : \"berlin\", \"street\" : \"Test 1\" , \"email\" : \"test@test.de\", \"phone\" : \"98749874\", \"zip\": \"12345\" }"
}
}
}The payment response contains redirect url and the response from payever is set to createPaymentResponse custom field.
The customer has to be redirected by the redirect_url (or open it in iframe) to finalize the payment.
A commercetools payment with createPaymentResponse field with the response above.
{
"amountPlanned": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 10000,
"fractionDigits": 2
},
"paymentMethodInfo": {
"paymentInterface": "ctp-payever-integration"
},
"custom": {
"type": {
"typeId": "type",
"id": "9798d6a3-13e1-4c4c-a868-7048cffeae8b"
},
"fields": {
"payeverBusinessUuid": "815c5953-6881-11e7-9835-52540073a0b6",
"commercetoolsProjectKey": "test121",
"createPaymentV2Request": "{\"amount\": 100, \"fee\": 0, \"order_id\": \"000001\", \"currency\": \"EUR\", \"payment_method\": \"zinia_bnpl_de\", \"cart\": [{\"name\": \"Product name\", \"price\": 100, \"quantity\": 1, \"description\": \"Product description\", \"sku\": \"4550330381882\", \"identifier\": \"4550330381882\"}],\"billing_address\": {\"salutation\": \"mr\", \"first_name\": \"Payever\", \"last_name\": \"Test\", \"street\": \"On Campus 5\", \"zip\": \"48712\", \"country\": \"DE\", \"city\": \"Gescher\"}, \"email\": \"test@test.de\", \"phone\": \"+4940912345678\", \"payment_data\": {\"force_redirect\": true }}",
"createPaymentResponse": "https://linkup.demo.cf.zinia.com/03c7xxxx-9721-42c1-843d-1905d518732b?documentCountry=DE"
}
},
}
Create a payment with splits using api v3 version: payever API V3 documentation
There is an option to use splits if it is needed to divide the payment between multiple business accounts.
Here's an example of the createPaymentV3Request custom field value for Credit Cards using payment splits:
{
"purchase": {
"amount": 210,
"currency": "EUR",
"country": "DE",
"delivery_fee": 10
},
"reference": "000001",
"payment_issuer": "verifone",
"payment_method": "credit_card",
"customer": {
"type": "person",
"gender": "male",
"birthdate": "1990-01-30",
"phone": "+4940912345678",
"email": "test@test.com",
"social_security_number": "12345678"
},
"cart": [
{
"name": "Product name",
"unit_price": 100,
"total_amount": 200,
"quantity": 2,
"description": "Product description",
"sku": "4550330381882",
"identifier": "4550330381882"
}
],
"shipping_option": {
"name": "Free",
"carrier": "DHL",
"category": "pickup",
"price": 0,
"tax_rate": 0,
"tax_amount": 0,
"details": {
"timeslot": "2023-02-30",
"pickup_location": {
"id": "12345",
"name": "of3",
"address": {
"first_name": "Grün",
"last_name": "Ampel",
"street": "Test 12",
"street_number": "12",
"salutation": "mr",
"zip": "38889",
"country": "DE",
"city": "Elbingerode (Harz)",
"organization_name": "Test",
"street_line_2": "Test line 2",
"street_name": "Test",
"house_extension": "A"
}
}
}
},
"billing_address": {
"first_name": "Grün",
"last_name": "Ampel",
"street": "Test 12",
"street_number": "12",
"salutation": "mr",
"zip": "38889",
"country": "DE",
"city": "Elbingerode (Harz)",
"organization_name": "Test",
"street_line_2": "Test line 2",
"street_name": "Test",
"house_extension": "A"
},
"splits": [
{
"type": "marketplace",
"identifier": "{{business_uuid1}}",
"amount": {
"value": 150,
"currency": "EUR"
},
"surcharges": {
"delivery_fee": 10
},
"reference": "{{unique-split-reference1}}",
"description": "{{split_description1}}"
},
{
"type": "marketplace",
"identifier": "{{business_uuid2}}",
"amount": {
"value": 50,
"currency": "EUR"
},
"reference": "{{unique-split-reference2}}",
"description": "{{split_description2}}"
}
]
}
Important - "purchase.delivery_fee": "10" - must be equal of all splits.surcharges.delivery_fee values or isn't needed to send at all;"reference": "000001" - will be as reference_extra property of each payment split."splits.identifier": "{{business_uuid1}}" - these are business account uuid between which the payment has be divided."splits.reference": "{{unique-split-reference}}" - payment split unique reference for further use in capture/refund/cancel actions.
An example of payment setCustomField action with the generated component data above.
{
"version": "PAYMENT_VERSION",
"actions": [
{
"action": "setCustomField",
"name": "createPaymentV3Request",
"value": "{ \"purchase\": { \"amount\": 210, \"currency\": \"EUR\", \"country\": \"DE\", \"delivery_fee\": 10 }, \"reference\": \"000001\", \"payment_method\": \"zinia_bnpl_de\", \"customer\": { \"type\": \"person\", \"gender\": \"male\", \"birthdate\": \"1990-01-30\", \"phone\": \"+4940912345678\", \"email\": \"test@test.com\", \"social_security_number\": \"12345678\" }, \"cart\": [ { \"name\": \"Product name\", \"unit_price\": 100, \"total_amount\": 200, \"quantity\": 2, \"description\": \"Product description\", \"sku\": \"4550330381882\", \"identifier\": \"4550330381882\" } ], \"shipping_option\": { \"name\": \"Free\", \"carrier\": \"DHL\", \"category\": \"pickup\", \"price\": 0, \"tax_rate\": 0, \"tax_amount\": 0, \"details\": { \"timeslot\": \"2023-02-30\", \"pickup_location\": { \"id\": \"12345\", \"name\": \"of3\", \"address\": { \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"street\": \"Test 12\", \"street_number\": \"12\", \"salutation\": \"mr\", \"zip\": \"38889\", \"country\": \"DE\", \"city\": \"Elbingerode (Harz)\", \"organization_name\": \"Test\", \"street_line_2\": \"Test line 2\", \"street_name\": \"Test\", \"house_extension\": \"A\" } } } }, \"billing_address\": { \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"street\": \"Test 12\", \"street_number\": \"12\", \"salutation\": \"mr\", \"zip\": \"38889\", \"country\": \"DE\", \"city\": \"Elbingerode (Harz)\", \"organization_name\": \"Test\", \"street_line_2\": \"Test line 2\", \"street_name\": \"Test\", \"house_extension\": \"A\" },\"splits\": [{\"type\": \"marketplace\",\"identifier\": \"{{business_uuid1}}\",\"amount\": {\"value\": 150,\"currency\": \"EUR\"},\"reference\": \"{{unique-split-reference1}}\",\"description\": \"{{split_description1}}\"},{\"type\": \"marketplace\",\"identifier\": \"{{business_uuid2}}\",\"amount\": {\"value\": 50,\"currency\": \"EUR\"},\"reference\": \"{{unique-split-reference2}}\",\"description\": \"{{split_description2}}\"}]}"
}
]
}
The commercetools payment representation example with createPaymentV3Request request.
{
"amountPlanned": {
"currencyCode": "EUR",
"centAmount": 21000
},
"paymentMethodInfo": {
"paymentInterface": "ctp-payever-integration"
},
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-payment-type"
},
"fields": {
"payeverBusinessUuid": "{{business_uuid1}}",
"commercetoolsProjectKey": "YOUR_COMMERCETOOLS_PROJECT_KEY",
"createPaymentV3Request": "{ \"purchase\": { \"amount\": 210, \"currency\": \"EUR\", \"country\": \"DE\", \"delivery_fee\": 10 }, \"reference\": \"000001\", \"payment_method\": \"zinia_bnpl_de\", \"customer\": { \"type\": \"person\", \"gender\": \"male\", \"birthdate\": \"1990-01-30\", \"phone\": \"+4940912345678\", \"email\": \"test@test.com\", \"social_security_number\": \"12345678\" }, \"cart\": [ { \"name\": \"Product name\", \"unit_price\": 100, \"total_amount\": 200, \"quantity\": 2, \"description\": \"Product description\", \"sku\": \"4550330381882\", \"identifier\": \"4550330381882\" } ], \"shipping_option\": { \"name\": \"Free\", \"carrier\": \"DHL\", \"category\": \"pickup\", \"price\": 0, \"tax_rate\": 0, \"tax_amount\": 0, \"details\": { \"timeslot\": \"2023-02-30\", \"pickup_location\": { \"id\": \"12345\", \"name\": \"of3\", \"address\": { \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"street\": \"Test 12\", \"street_number\": \"12\", \"salutation\": \"mr\", \"zip\": \"38889\", \"country\": \"DE\", \"city\": \"Elbingerode (Harz)\", \"organization_name\": \"Test\", \"street_line_2\": \"Test line 2\", \"street_name\": \"Test\", \"house_extension\": \"A\" } } } }, \"billing_address\": { \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"street\": \"Test 12\", \"street_number\": \"12\", \"salutation\": \"mr\", \"zip\": \"38889\", \"country\": \"DE\", \"city\": \"Elbingerode (Harz)\", \"organization_name\": \"Test\", \"street_line_2\": \"Test line 2\", \"street_name\": \"Test\", \"house_extension\": \"A\" },\"splits\": [{\"type\": \"marketplace\",\"identifier\": \"{{business_uuid1}}\",\"amount\": {\"value\": 150,\"currency\": \"EUR\"},\"reference\": \"{{unique-split-reference1}}\",\"description\": \"{{split_description1}}\"},{\"type\": \"marketplace\",\"identifier\": \"{{business_uuid2}}\",\"amount\": {\"value\": 50,\"currency\": \"EUR\"},\"reference\": \"{{unique-split-reference2}}\",\"description\": \"{{split_description2}}\"}]}"
}
}
}
Response:
The payment response contains redirect url and the response from payever is set to createPaymentResponse custom field.
The customer has to be redirected by the redirect_url (or open it in iframe) to finalize the payment.
A commercetools payment with createPaymentResponse field with the response above. Click to expand.
The commercetools payment representation example with createPaymentV3Request request.
{
"amountPlanned": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 21000,
"fractionDigits": 2
},
"paymentMethodInfo": {
"paymentInterface": "ctp-payever-integration"
},
"custom": {
"type": {
"typeId": "type",
"id": "9798d6a3-13e1-4c4c-a868-7048cffeae8b"
},
"fields": {
"payeverBusinessUuid": "{{business_uuid1}}",
"commercetoolsProjectKey": "YOUR_COMMERCETOOLS_PROJECT_KEY",
"createPaymentV3Request": "{ \"purchase\": { \"amount\": 210, \"currency\": \"EUR\", \"country\": \"DE\", \"delivery_fee\": 10 }, \"reference\": \"000001\", \"payment_method\": \"zinia_bnpl_de\", \"customer\": { \"type\": \"person\", \"gender\": \"male\", \"birthdate\": \"1990-01-30\", \"phone\": \"+4940912345678\", \"email\": \"test@test.com\", \"social_security_number\": \"12345678\" }, \"cart\": [ { \"name\": \"Product name\", \"unit_price\": 100, \"total_amount\": 200, \"quantity\": 2, \"description\": \"Product description\", \"sku\": \"4550330381882\", \"identifier\": \"4550330381882\" } ], \"shipping_option\": { \"name\": \"Free\", \"carrier\": \"DHL\", \"category\": \"pickup\", \"price\": 0, \"tax_rate\": 0, \"tax_amount\": 0, \"details\": { \"timeslot\": \"2023-02-30\", \"pickup_location\": { \"id\": \"12345\", \"name\": \"of3\", \"address\": { \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"street\": \"Test 12\", \"street_number\": \"12\", \"salutation\": \"mr\", \"zip\": \"38889\", \"country\": \"DE\", \"city\": \"Elbingerode (Harz)\", \"organization_name\": \"Test\", \"street_line_2\": \"Test line 2\", \"street_name\": \"Test\", \"house_extension\": \"A\" } } } }, \"billing_address\": { \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"street\": \"Test 12\", \"street_number\": \"12\", \"salutation\": \"mr\", \"zip\": \"38889\", \"country\": \"DE\", \"city\": \"Elbingerode (Harz)\", \"organization_name\": \"Test\", \"street_line_2\": \"Test line 2\", \"street_name\": \"Test\", \"house_extension\": \"A\" },\"splits\": [{\"type\": \"marketplace\",\"identifier\": \"{{business_uuid1}}\",\"amount\": {\"value\": 150,\"currency\": \"EUR\"},\"reference\": \"{{unique-split-reference1}}\",\"description\": \"{{split_description1}}\"},{\"type\": \"marketplace\",\"identifier\": \"{{business_uuid2}}\",\"amount\": {\"value\": 50,\"currency\": \"EUR\"},\"reference\": \"{{unique-split-reference2}}\",\"description\": \"{{split_description2}}\"}]}",
"createPaymentResponse": "https://checkout.staging.devpayever.com/de/pay/api-call/98b9817c-058a-4cbc-bc3b-d09b72ae7392?channelSetId=caf060a7-7338-44f2-bcff-bf42d4ad05be"
}
},
}
Submit a payment with v3 api version for B2B payment: payever API V3 documentation
Here's an example of the submitPaymentV3Request custom field value for B2B payment:
{
"purchase": {
"amount": 200,
"currency": "EUR",
"country": "DE",
"delivery_fee": 0
},
"reference": "000001",
"payment_method": "allianz_trade_b2b_bnpl",
"customer": {
"type": "organization",
"gender": "male",
"birthdate": "1990-01-30",
"phone": "+4912345678",
"email": "test@test.com",
"social_security_number": "12345678"
},
"company": {
"type": "limited",
"name": "google",
"email": "company@email.com",
"registration_number": "12345",
"registration_location": "DE, Hamburg",
"tax_id": "98765",
"homepage": "http://www.google.com",
"external_id": "112233"
},
"cart": [
{
"name": "Product name",
"unit_price": 100,
"total_amount": 200,
"quantity": 2,
"description": "Product description",
"sku": "4550330381882",
"identifier": "4550330381882"
}
],
"billing_address": {
"first_name": "Grün",
"last_name": "Ampel",
"street": "Test 12",
"street_number": "12",
"salutation": "mr",
"zip": "38889",
"country": "DE",
"city": "Elbingerode (Harz)",
"organization_name": "Test",
"street_line_2": "Test line 2",
"street_name": "Test",
"house_extension": "A"
},
"options": {
"allow_separate_shipping_address": true,
"allow_cart_step": false,
"allow_billing_step": false,
"allow_shipping_step": false,
"use_inventory": true,
"use_styles": true,
"salutation_mandatory": true,
"phone_mandatory": false,
"birthdate_mandatory": false,
"test_mode": true,
"reusable": false,
"hide_logo": true,
"hide_imprint": true,
"disable_validation": true
},
"plugin_version": "1.0.2",
"channel": {
"name": "commercetools"
}
}
An example of payment setCustomField action with the generated component data above.
{
"version": "PAYMENT_VERSION",
"actions": [
{
"action": "setCustomField",
"name": "submitPaymentV3Request",
"value": "{ \"purchase\": { \"amount\": 200, \"currency\": \"EUR\", \"country\": \"DE\", \"delivery_fee\": 0 }, \"reference\": \"000001\", \"payment_method\": \"allianz_trade_b2b_bnpl\", \"customer\": { \"type\": \"organization\", \"gender\": \"male\", \"birthdate\": \"1990-01-30\", \"phone\": \"+4912345678\", \"email\": \"test@test.com\", \"social_security_number\": \"12345678\" }, \"company\": { \"type\": \"limited\", \"name\": \"google\", \"email\": \"company@email.com\", \"registration_number\": \"12345\", \"registration_location\": \"DE\", \"tax_id\": \"333\", \"homepage\": \"http://www.google.com\", \"external_id\": \"999\" }, \"cart\": [ { \"name\": \"Product name\", \"unit_price\": 100, \"total_amount\": 200, \"quantity\": 2, \"description\": \"Product description\", \"sku\": \"4550330381882\", \"identifier\": \"4550330381882\" } ], \"shipping_option\": { \"name\": \"Free\", \"carrier\": \"DHL\", \"category\": \"pickup\", \"price\": 0, \"tax_rate\": 0, \"tax_amount\": 0, \"details\": { \"timeslot\": \"2023-02-30\", \"pickup_location\": { \"id\": \"12345\", \"name\": \"of3\", \"address\": { \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"street\": \"Test 12\", \"street_number\": \"12\", \"salutation\": \"mr\", \"zip\": \"38889\", \"country\": \"DE\", \"city\": \"Elbingerode (Harz)\", \"organization_name\": \"Test\", \"street_line_2\": \"Test line 2\", \"street_name\": \"Test\", \"house_extension\": \"A\" } } } }, \"billing_address\": { \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"street\": \"Test 12\", \"street_number\": \"12\", \"salutation\": \"mr\", \"zip\": \"38889\", \"country\": \"DE\", \"city\": \"Elbingerode (Harz)\", \"organization_name\": \"Test\", \"street_line_2\": \"Test line 2\", \"street_name\": \"Test\", \"house_extension\": \"A\" }, \"options\": { \"allow_separate_shipping_address\": true, \"allow_cart_step\": false, \"allow_billing_step\": false, \"allow_shipping_step\": false, \"use_inventory\": true, \"use_styles\": true, \"salutation_mandatory\": true, \"phone_mandatory\": false, \"birthdate_mandatory\": false, \"test_mode\": true, \"reusable\": false, \"hide_logo\": true, \"hide_imprint\": true, \"disable_validation\": true }, \"plugin_version\": \"1.0.2\", \"channel\": { \"name\": \"commercetools\" } }"
}
]
}
The commercetools payment representation example with createPaymentV3Request request.
{
"amountPlanned": {
"currencyCode": "EUR",
"centAmount": 20000
},
"paymentMethodInfo": {
"paymentInterface": "ctp-payever-integration"
},
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-payment-type"
},
"fields": {
"payeverBusinessUuid": "YOUR_PAYEVER_BUSINESS_UUID",
"commercetoolsProjectKey": "YOUR_COMMERCETOOLS_PROJECT_KEY",
"createPaymentV3Request": "{ \"purchase\": { \"amount\": 200, \"currency\": \"EUR\", \"country\": \"DE\", \"delivery_fee\": 0 }, \"reference\": \"000001\", \"payment_method\": \"allianz_trade_b2b_bnpl\", \"customer\": { \"type\": \"organization\", \"gender\": \"male\", \"birthdate\": \"1990-01-30\", \"phone\": \"+4912345678\", \"email\": \"test@test.com\", \"social_security_number\": \"12345678\" }, \"company\": { \"type\": \"limited\", \"name\": \"google\", \"email\": \"company@email.com\", \"registration_number\": \"12345\", \"registration_location\": \"DE\", \"tax_id\": \"333\", \"homepage\": \"http://www.google.com\", \"external_id\": \"999\" }, \"cart\": [ { \"name\": \"Product name\", \"unit_price\": 100, \"total_amount\": 200, \"quantity\": 2, \"description\": \"Product description\", \"sku\": \"4550330381882\", \"identifier\": \"4550330381882\" } ], \"shipping_option\": { \"name\": \"Free\", \"carrier\": \"DHL\", \"category\": \"pickup\", \"price\": 0, \"tax_rate\": 0, \"tax_amount\": 0, \"details\": { \"timeslot\": \"2023-02-30\", \"pickup_location\": { \"id\": \"12345\", \"name\": \"of3\", \"address\": { \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"street\": \"Test 12\", \"street_number\": \"12\", \"salutation\": \"mr\", \"zip\": \"38889\", \"country\": \"DE\", \"city\": \"Elbingerode (Harz)\", \"organization_name\": \"Test\", \"street_line_2\": \"Test line 2\", \"street_name\": \"Test\", \"house_extension\": \"A\" } } } }, \"billing_address\": { \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"street\": \"Test 12\", \"street_number\": \"12\", \"salutation\": \"mr\", \"zip\": \"38889\", \"country\": \"DE\", \"city\": \"Elbingerode (Harz)\", \"organization_name\": \"Test\", \"street_line_2\": \"Test line 2\", \"street_name\": \"Test\", \"house_extension\": \"A\" }, \"options\": { \"allow_separate_shipping_address\": true, \"allow_cart_step\": false, \"allow_billing_step\": false, \"allow_shipping_step\": false, \"use_inventory\": true, \"use_styles\": true, \"salutation_mandatory\": true, \"phone_mandatory\": false, \"birthdate_mandatory\": false, \"test_mode\": true, \"reusable\": false, \"hide_logo\": true, \"hide_imprint\": true, \"disable_validation\": true }, \"plugin_version\": \"1.0.2\", \"channel\": { \"name\": \"commercetools\" } }"
}
}
}
Response
The submit payment payment contains the response from payever which is set to submitPaymentResponse custom field.
A commercetools payment with submitPaymentResponse field with the response above. Click to expand.
{
"amountPlanned": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 20000,
"fractionDigits": 2
},
"paymentMethodInfo": {
"paymentInterface": "ctp-payever-integration"
},
"custom": {
"type": {
"typeId": "type",
"id": "9798d6a3-13e1-4c4c-a868-7048cffeae8b"
},
"fields": {
"payeverBusinessUuid": "815c5953-6881-11e7-9835-52540073a0b6",
"commercetoolsProjectKey": "test121",
"submitPaymentV3Request": "{ \"purchase\": { \"amount\": 200, \"currency\": \"EUR\", \"country\": \"DE\", \"delivery_fee\": 0 }, \"reference\": \"000001\", \"payment_method\": \"credit_card\", \"payment_issuer\": \"verifone\", \"customer\": { \"type\": \"person\", \"gender\": \"male\", \"birthdate\": \"1990-01-30\", \"phone\": \"+4940912345678\", \"email\": \"test@test.com\", \"social_security_number\": \"12345678\" }, \"cart\": [ { \"name\": \"Product name\", \"unit_price\": 100, \"total_amount\": 200, \"quantity\": 2, \"description\": \"Product description\", \"sku\": \"4550330381882\", \"identifier\": \"4550330381882\" } ], \"billing_address\": { \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"street\": \"Test 12\", \"street_number\": \"12\", \"salutation\": \"mr\", \"zip\": \"38889\", \"country\": \"DE\", \"city\": \"Elbingerode (Harz)\", \"organization_name\": \"Test\", \"street_line_2\": \"Test line 2\", \"street_name\": \"Test\", \"house_extension\": \"A\" }, \"plugin_version\": \"1.0.2\", \"channel\": { \"name\": \"commercetools\" }, \"payment_data\": { \"reuseToken\": \"6fd8ab53-6681-4a43-bea5-aff36cee9936\", \"issueReuseToken\": true } }",
"submitPaymentResponse": "{ \"id\": \"69d78164-e734-4dee-8b78-d9ceec773f20\", \"amount\": 200, \"channel\": \"commercetools\", \"currency\": \"EUR\", \"address\": { \"email\": \"test@test.de\", \"salutation\": \"\", \"city\": \"Berlin\", \"street\": \"Test 12\", \"country\": \"DE\", \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"zip_code\": \"38889\" }, \"company\": { \"type\": \"limited\", \"name\": \"google\", \"registrationNumber\": \"12345\", \"registrationLocation\": \"DE, Hamburg\", \"taxId\": \"98765\", \"homepage\": \"https://test.com\", \"externalId\": \"112233\" }, \"created_at\": \"2021-04-19T14:51:48.865Z\", \"customer_email\": \"test@test.de\", \"customer_name\": \"Grün Ampel\", \"delivery_fee\": 0, \"down_payment\": 0, \"merchant_name\": \"payever\", \"payment_fee\": 0, \"payment_type\": \"allianz_trade_b2b_bnpl\", \"reference\": \"000001\", \"specificStatus\": \"Quoted\", \"status\": \"STATUS_ACCEPTED\", \"total\": 200}"
}
}
}
Important:
Depending on "status" of payment the customer has to be redirected to confirmation or declining page.
Submit a payment with v3 api version for Credit Cards
In order to make submit payment request for Credit Cards there is needed to keep token on the merchant end which can be obtained from last commercetools payment transaction. The commercetools payment representation after a successful payment with Credit Cards:
{
"id": "ca068e31-c2f1-410a-912d-d12bf3c645b2",
"key": "14",
"amountPlanned": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 20000,
"fractionDigits": 2
},
"paymentMethodInfo": {
"paymentInterface": "ctp-payever-integration"
},
"transactions": [
{
"id": "98d62c56-9a72-4b96-8cb7-f9fe68181085",
"type": "Authorization",
"amount": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 20000,
"fractionDigits": 2
},
"interactionId": "77bd18b5-6531-499b-a6df-4e841ad80b50",
"state": "Success",
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-transaction-payment-type"
},
"fields": {
"paymentDetails": "{ \"token\": \"6fd8ab53-6681-4a43-bea5-aff36cee9936\", \"bin\": \"test bin\", \"expiryMonth\": 12, \"expiryYear\": 2027, \"LastFour\": \"1234\", \"cardHolderName\": \"Test Test\", \"tokenExpiryDate\":\"2025-05-31T00:00:00Z\", \"tokenScope\": \"test_scope\" , \"tokenStatus\": \"ACTIVE\", \"currency\": \"EUR\", \"issuerCountry\": \"DE\", \"issuerName\": \"verifone\", \"brand\": \"VISA\"}"
}
}
}
]
}
There is JSON in payment details of the transaction custom fields which contains last Credit Card payments details including token that might be used for the following payments without entering credit card data.
Here's an example of the submitPaymentV3Request custom field value for Credit Card payments with saved token:
{
"purchase": {
"amount": 200,
"currency": "EUR",
"country": "DE",
"delivery_fee": 0
},
"reference": "000001",
"payment_method": "credit_card",
"payment_issuer": "verifone",
"customer": {
"type": "person",
"gender": "male",
"birthdate": "1990-01-30",
"phone": "+4940912345678",
"email": "test@test.com",
"social_security_number": "12345678"
},
"cart": [
{
"name": "Product name",
"unit_price": 100,
"total_amount": 200,
"quantity": 2,
"description": "Product description",
"sku": "4550330381882",
"identifier": "4550330381882"
}
],
"billing_address": {
"first_name": "Grün",
"last_name": "Ampel",
"street": "Test 12",
"street_number": "12",
"salutation": "mr",
"zip": "38889",
"country": "DE",
"city": "Elbingerode (Harz)",
"organization_name": "Test",
"street_line_2": "Test line 2",
"street_name": "Test",
"house_extension": "A"
},
"plugin_version": "1.0.2",
"channel": {
"name": "commercetools"
},
"payment_data": {
"reuseToken": "6fd8ab53-6681-4a43-bea5-aff36cee9936",
"issueReuseToken": true
}
}
Important
"payment_data": {
"reuseToken": "6fd8ab53-6681-4a43-bea5-aff36cee9936",
"issueReuseToken": true
}
the expiration time of token has to be controlled on the merchants end.
An example of payment setCustomField action with the generated component data above.
{
"version": "PAYMENT_VERSION",
"actions": [
{
"action": "setCustomField",
"name": "submitPaymentV3Request",
"value": "{ \"purchase\": { \"amount\": 200, \"currency\": \"EUR\", \"country\": \"DE\", \"delivery_fee\": 0 }, \"reference\": \"000001\", \"payment_method\": \"credit_card\", \"payment_issuer\": \"verifone\", \"customer\": { \"type\": \"person\", \"gender\": \"male\", \"birthdate\": \"1990-01-30\", \"phone\": \"+4940912345678\", \"email\": \"test@test.com\", \"social_security_number\": \"12345678\" }, \"cart\": [ { \"name\": \"Product name\", \"unit_price\": 100, \"total_amount\": 200, \"quantity\": 2, \"description\": \"Product description\", \"sku\": \"4550330381882\", \"identifier\": \"4550330381882\" } ], \"billing_address\": { \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"street\": \"Test 12\", \"street_number\": \"12\", \"salutation\": \"mr\", \"zip\": \"38889\", \"country\": \"DE\", \"city\": \"Elbingerode (Harz)\", \"organization_name\": \"Test\", \"street_line_2\": \"Test line 2\", \"street_name\": \"Test\", \"house_extension\": \"A\" }, \"plugin_version\": \"1.0.2\", \"channel\": { \"name\": \"commercetools\" }, \"payment_data\": { \"reuseToken\": \"6fd8ab53-6681-4a43-bea5-aff36cee9936\", \"issueReuseToken\": true } }"
}
]
}
The commercetools payment representation example with createPaymentV3Request request.
{
"amountPlanned": {
"currencyCode": "EUR",
"centAmount": 20000
},
"paymentMethodInfo": {
"paymentInterface": "ctp-payever-integration"
},
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-payment-type"
},
"fields": {
"payeverBusinessUuid": "YOUR_PAYEVER_BUSINESS_UUID",
"commercetoolsProjectKey": "YOUR_COMMERCETOOLS_PROJECT_KEY",
"submitPaymentV3Request": "{ \"purchase\": { \"amount\": 200, \"currency\": \"EUR\", \"country\": \"DE\", \"delivery_fee\": 0 }, \"reference\": \"000001\", \"payment_method\": \"credit_card\", \"payment_issuer\": \"verifone\", \"customer\": { \"type\": \"person\", \"gender\": \"male\", \"birthdate\": \"1990-01-30\", \"phone\": \"+4940912345678\", \"email\": \"test@test.com\", \"social_security_number\": \"12345678\" }, \"cart\": [ { \"name\": \"Product name\", \"unit_price\": 100, \"total_amount\": 200, \"quantity\": 2, \"description\": \"Product description\", \"sku\": \"4550330381882\", \"identifier\": \"4550330381882\" } ], \"billing_address\": { \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"street\": \"Test 12\", \"street_number\": \"12\", \"salutation\": \"mr\", \"zip\": \"38889\", \"country\": \"DE\", \"city\": \"Elbingerode (Harz)\", \"organization_name\": \"Test\", \"street_line_2\": \"Test line 2\", \"street_name\": \"Test\", \"house_extension\": \"A\" }, \"plugin_version\": \"1.0.2\", \"channel\": { \"name\": \"commercetools\" }, \"payment_data\": { \"reuseToken\": \"6fd8ab53-6681-4a43-bea5-aff36cee9936\", \"issueReuseToken\": true } }"
}
}
}
Response
The submit payment payment contains the response from payever which is set to submitPaymentResponse custom field.
A commercetools payment with submitPaymentResponse field with the response above.
{
"amountPlanned": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 20000,
"fractionDigits": 2
},
"paymentMethodInfo": {
"paymentInterface": "ctp-payever-integration"
},
"custom": {
"type": {
"typeId": "type",
"id": "9798d6a3-13e1-4c4c-a868-7048cffeae8b"
},
"fields": {
"payeverBusinessUuid": "815c5953-6881-11e7-9835-52540073a0b6",
"commercetoolsProjectKey": "test121",
"submitPaymentV3Request": "{ \"purchase\": { \"amount\": 200, \"currency\": \"EUR\", \"country\": \"DE\", \"delivery_fee\": 0 }, \"reference\": \"000001\", \"payment_method\": \"credit_card\", \"payment_issuer\": \"verifone\", \"customer\": { \"type\": \"person\", \"gender\": \"male\", \"birthdate\": \"1990-01-30\", \"phone\": \"+4940912345678\", \"email\": \"test@test.com\", \"social_security_number\": \"12345678\" }, \"cart\": [ { \"name\": \"Product name\", \"unit_price\": 100, \"total_amount\": 200, \"quantity\": 2, \"description\": \"Product description\", \"sku\": \"4550330381882\", \"identifier\": \"4550330381882\" } ], \"billing_address\": { \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"street\": \"Test 12\", \"street_number\": \"12\", \"salutation\": \"mr\", \"zip\": \"38889\", \"country\": \"DE\", \"city\": \"Elbingerode (Harz)\", \"organization_name\": \"Test\", \"street_line_2\": \"Test line 2\", \"street_name\": \"Test\", \"house_extension\": \"A\" }, \"plugin_version\": \"1.0.2\", \"channel\": { \"name\": \"commercetools\" }, \"payment_data\": { \"reuseToken\": \"6fd8ab53-6681-4a43-bea5-aff36cee9936\", \"issueReuseToken\": true } }",
"submitPaymentResponse": "{ \"id\": \"69d78164-e734-4dee-8b78-d9ceec773f20\", \"amount\": 200, \"channel\": \"commercetools\", \"currency\": \"EUR\", \"address\": { \"email\": \"test@test.de\", \"salutation\": \"\", \"city\": \"Berlin\", \"street\": \"Test 12\", \"country\": \"DE\", \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"zip_code\": \"38889\" }, \"created_at\": \"2021-04-19T14:51:48.865Z\", \"customer_email\": \"test@test.de\", \"customer_name\": \"Grün Ampel\", \"delivery_fee\": 0, \"down_payment\": 0, \"merchant_name\": \"payever\", \"payment_fee\": 0, \"payment_type\": \"credit_card\", \"payment_issuer\": \"verifone\", \"reference\": \"000001\", \"status\": \"STATUS_PAID\", \"total\": 200, \"shipping_address\": { \"first_name\": \"Grün\", \"last_name\": \"Ampel\", \"street\": \"Test\", \"street_number\": \"12\", \"city\": \"Berlin\", \"country\": \"DE\", \"phone\": \"+4912345678\", \"zip_code\": \"38889\" } }"
}
}
}
Important
Depending on "status" of payment the customer has to be redirected to confirmation or declining page.
Error handling
In case you encounter errors in your integration, refer to the following:
Extension module errors:
If you receive a non-HTTP 200 response, use the commercetools payment interface interactions to troubleshoot the response.
Interface interactions can represent a request sent to payever, a response, or a notification received from payever.
Shopper tries to pay a different amount than the actual order amount:
After redirect and before the actual finalization of the payment at the provider's page, the shopper is still able to change the cart's amount within the second tab.
If the shopper decides to change the cart's amount within the second tab and finalize payment within the first tab, then according to payment amount [validation](#step-1-commercetools-checkout-validations) an error has to be shown and order creation must be declined. In such a case, it might be reasonable to cancel or refund the invalid payment.
In order for commercetools-payever-integration to know which project and merchant account it should communicate with, so payeverBusinessUuid and commercetoolsProjectKey custom fields must be provided on payment creation.
Bad Practices:
Never delete or un-assign created payment objects during checkout from the cart. If required - clean up unused/obsolete payment objects by another asynchronous process instead.
Step 5: Shipping goods
Manual shipping goods
For payment methods that support separate authorization and capture, you also have the option to capture the payment later, for example only after the goods have been shipped. This also allows you to cancel the payment/authorization.
Make an API call to shipping goods a payment:
To shipping goods a payment manually, add a transaction with type Charge and state Initial to the commercetools payment.
{
"action": "addTransaction",
"transaction": {
"type": "Charge",
"amount": {
"currencyCode": "EUR",
"centAmount": 1000
},
"state": "Initial"
}
}
Extension module will update the transaction with Success transaction state and interactionId field with payment id from the payever response:
{
"id": "a2904b53-d79a-484e-8954-ee4c3b6de1a2",
"type": "Charge",
"amount": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 1000,
"fractionDigits": 2
},
"interactionId": "79bd18b5-6531-499b-a6df-4e841ad80b50",
"state": "Success"
}
Request/response between payever and extension module are stored in interfaceInteraction field of the payment with type shippingGoodsPayment: The commercetools payment representation after a successful shipping goods:
{
"transactions": [
{
"id": "f91e1fd9-cf08-41f8-9785-ed4b76658e39",
"type": "Authorization",
"amount": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 1000,
"fractionDigits": 2
},
"interactionId": "79bd18b5-6531-499b-a6df-4e841ad80b50",
"state": "Success"
},
{
"id": "a2904b53-d79a-484e-8954-ee4c3b6de1a2",
"type": "Charge",
"amount": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 1000,
"fractionDigits": 2
},
"interactionId": "79bd18b5-6531-499b-a6df-4e841ad80b50",
"state": "Success"
}
],
"interfaceInteractions": [
{
"type": {
"typeId": "type",
"id": "e6a36f88-58a4-46f5-998b-214973b0427b"
},
"fields": {
"type": "shippingGoodsPayment",
"request":"{\"paymentId\":\"e6a36f88-58a4-46f5-998b-214973b0427b\",\"amount\":\"10\"}",
"response":"{\"id\":\"e6a36f88-58a4-46f5-998b-214973b0427b\",\"status\":\"STATUS_PAID\",\"specific_status\":\"ORDER_SHIPPED\",\"merchant_name\":\"ANWR Media GmbH\",\"customer_name\":\"Thu Nguyen\",\"payment_type\":\"zinia_bnpl_de\",\"customer_email\":\"ndtthu@gmail.com\",\"created_at\":\"2023-06-16T07:09:32.000Z\",\"updated_at\":\"2023-06-16T07:16:33.000Z\",\"channel\":\"commercetools\",\"channel_type\":null,\"channel_source\":null,\"reference\":\"2f80c7e2\",\"amount\":10.00,\"total\":10.00,\"currency\":\"EUR\",\"delivery_fee\":0,\"payment_fee\":0,\"down_payment\":0,\"payment_details\":{\"birthday\":null,\"order_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"otp_id\":null,\"redirect_url\":\"https://linkup.demo.cf.zinia.com/0946b9f4-4ac5-470e-963d-8504c7ef8faf?documentCountry=DE\",\"expiration_time\":\"2023-06-16T07:19:33.633Z\",\"advertising_accepted\":true,\"conditions_accepted\":true,\"finalize_unique_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"receipt_unique_id\":null,\"reservation_unique_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"usage_text\":\"\",\"shop_user_session\":null},\"payment_details_array\":{\"birthday\":null,\"order_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"otp_id\":null,\"redirect_url\":\"https://linkup.demo.cf.zinia.com/0946b9f4-4ac5-470e-963d-8504c7ef8faf?documentCountry=DE\",\"expiration_time\":\"2023-06-16T07:19:33.633Z\",\"advertising_accepted\":true,\"conditions_accepted\":true,\"finalize_unique_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"receipt_unique_id\":null,\"reservation_unique_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"usage_text\":\"\",\"shop_user_session\":null},\"address\":{\"city\":\"Gescher\",\"country\":\"DE\",\"country_name\":\"DE\",\"email\":\"ndtthu@gmail.com\",\"first_name\":\"Thu\",\"last_name\":\"Nguyen\",\"phone\":\"+4915212341234\",\"salutation\":\"\",\"street\":\"On Campus 5\",\"zip_code\":\"48712\"},\"shipping_address\":{\"city\":\"Gescher\",\"country\":\"DE\",\"country_name\":\"DE\",\"first_name\":\"Thu\",\"last_name\":\"Nguyen\",\"salutation\":\"\",\"street\":\"On Campus 5\",\"zip_code\":\"48712\"}}",
"createdAt": "2023-06-23T14:22:02.668Z"
}
}
]
}
Retry shipping goods requests
To be able to retry shipping goods requests in case of failure, you need to add a custom field with key idempotencyKey to the custom type with key ctp-payever-integration-transaction-payment-type. The addTransaction action will look like following:
{
"action": "addTransaction",
"transaction": {
"type": "Charge",
"amount": {
"currencyCode": "EUR",
"centAmount": 500
},
"state": "Initial",
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-transaction-payment-type"
},
"fields": {
"idempotencyKey": "your-unique-idempotency-key"
}
}
}
}
By default it uses transaction ID as the idempotency key when custom field with key idempotencyKey is not specified.
Follow these recommendations when using the idempotency key:
-
idempotencyKeymust be unique per request so that in case the request fails, it can be retried with the same key. - Generate idempotency keys using the version 4 (random) UUID type to prevent two API credentials under the same account from accessing each other's responses.
- Use exponential backoff when retrying.
Custom manual shipping goods reference
If you need to customize the value of the manual shipping goods reference, add a transaction custom field with key reference to the custom type with key ctp-payever-integration-transaction-payment-type. The addTransaction action will look like following:
{
"action": "addTransaction",
"transaction": {
"type": "Charge",
"amount": {
"currencyCode": "EUR",
"centAmount": 500
},
"state": "Initial",
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-transaction-payment-type"
},
"fields": {
"reference": "your-custom-manual-capture-reference"
}
}
}
}
Shipping goods requests for payment splits
To be able to trigger shipping goods request for payment that was created with splits, you need to add a custom field with key splitReference to the transaction with custom type with key ctp-payever-integration-transaction-payment-type. The addTransaction action will look like following:
{
"action": "addTransaction",
"transaction": {
"type": "Charge",
"amount": {
"currencyCode": "EUR",
"centAmount": 16000
},
"state": "Initial",
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-transaction-payment-type"
},
"fields": {
"splitReference": {{unique-split-reference1}}
}
}
}
}
Follow these recommendations when using the split reference:
-
splitReferencemust be the same string that was sent in one of the splits in createPaymentV3Request.
More info on shipping goods
For more detailed information from payever's perspective, see following documentation
Step 6: Refund
Refund
If you want to return the funds to your shopper, for example if they returned an item, you need to make a Refund request.
Make an API call to refund a payment
Prerequisites
It is required that the payment has a transaction of type Authorization and state Success.
From Authorized transaction, the interactionId field is being used as paymentId for the payever refund request.
Steps
To make a (partial) refund, add at least one transaction with type Refund and state Initial to the commercetools payment.
It is possible to add multiple Refund transactions and all of them will be processed in parallel.
{
"action": "addTransaction",
"transaction": {
"type": "Refund",
"amount": {
"currencyCode": "EUR",
"centAmount": 1000
},
"state": "Initial"
}
}
Extension module will update the transaction with `Success` transaction state and `interactionId` field with payment id from the payever response:
{
"id": "a4504b99-d46e-484e-1344-ee4c3b6de1a2",
"type": "Refund",
"amount": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 1000,
"fractionDigits": 2
},
"interactionId": "77bd18b5-6531-499b-a6df-4e841ad80b50",
"state": "Pending"
}
Request/response between payever and extension module are stored in interfaceInteraction field of the payment with type refund.
The commercetools payment representation after a successful refund:
{
"id": "ca068e31-c2f1-410a-912d-d12bf3c645b2",
"key": "14",
"amountPlanned": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 1000,
"fractionDigits": 2
},
"paymentMethodInfo": {
"paymentInterface": "ctp-payever-integration"
},
"transactions": [
{
"id": "98d62c56-9a72-4b96-8cb7-f9fe68181085",
"type": "Authorization",
"amount": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 1000,
"fractionDigits": 2
},
"interactionId": "77bd18b5-6531-499b-a6df-4e841ad80b50",
"state": "Success"
},
{
"id": "5d3e8fc1-bdb7-4e34-b3e9-8b34c3f60135",
"type": "Refund",
"amount": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 1000,
"fractionDigits": 2
},
"interactionId": "77bd18b5-6531-499b-a6df-4e841ad80b50",
"state": "Success"
}
],
"interfaceInteractions": [
{
"type": {
"typeId": "type",
"id": "5d93411a-9736-43ba-9f4d-5f14158427ba"
},
"fields": {
"createdAt": "2023-06-19T16:17:14.247Z",
"request": "{\"paymentId\":\"77bd18b5-6531-499b-a6df-4e841ad80b50\",\"amount\":\"10\"}",
"response":"{\"id\":\"77bd18b5-6531-499b-a6df-4e841ad80b50\",\"status\":\"STATUS_REFUNDED\",\"merchant_name\":\"ANWR Media GmbH\",\"customer_name\":\"Thu Nguyen\",\"payment_type\":\"zinia_bnpl_de\",\"customer_email\":\"ndtthu@gmail.com\",\"created_at\":\"2023-06-16T07:09:32.000Z\",\"updated_at\":\"2023-06-16T07:16:33.000Z\",\"channel\":\"commercetools\",\"channel_type\":null,\"channel_source\":null,\"reference\":\"2f80c7e2\",\"amount\":10.00,\"total\":10.00,\"currency\":\"EUR\",\"delivery_fee\":0,\"payment_fee\":0,\"down_payment\":0,\"payment_details\":{\"birthday\":null,\"order_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"otp_id\":null,\"redirect_url\":\"https://linkup.demo.cf.zinia.com/0946b9f4-4ac5-470e-963d-8504c7ef8faf?documentCountry=DE\",\"expiration_time\":\"2023-06-16T07:19:33.633Z\",\"advertising_accepted\":true,\"conditions_accepted\":true,\"finalize_unique_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"receipt_unique_id\":null,\"reservation_unique_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"usage_text\":\"\",\"shop_user_session\":null},\"payment_details_array\":{\"birthday\":null,\"order_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"otp_id\":null,\"redirect_url\":\"https://linkup.demo.cf.zinia.com/0946b9f4-4ac5-470e-963d-8504c7ef8faf?documentCountry=DE\",\"expiration_time\":\"2023-06-16T07:19:33.633Z\",\"advertising_accepted\":true,\"conditions_accepted\":true,\"finalize_unique_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"receipt_unique_id\":null,\"reservation_unique_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"usage_text\":\"\",\"shop_user_session\":null},\"address\":{\"city\":\"Gescher\",\"country\":\"DE\",\"country_name\":\"DE\",\"email\":\"ndtthu@gmail.com\",\"first_name\":\"Thu\",\"last_name\":\"Nguyen\",\"phone\":\"+4915212341234\",\"salutation\":\"\",\"street\":\"On Campus 5\",\"zip_code\":\"48712\"},\"shipping_address\":{\"city\":\"Gescher\",\"country\":\"DE\",\"country_name\":\"DE\",\"first_name\":\"Thu\",\"last_name\":\"Nguyen\",\"salutation\":\"\",\"street\":\"On Campus 5\",\"zip_code\":\"48712\"}}",
"type": "refundPayment"
}
}
]
}
Retry refund requests
To be able to retry refund requests in case of failure, you need to add a custom field with key idempotencyKey to the custom type with key ctp-payever-integration-transaction-payment-type. The addTransaction action will look like following:
{
"action": "addTransaction",
"transaction": {
"type": "Refund",
"amount": {
"currencyCode": "EUR",
"centAmount": 500
},
"state": "Initial",
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-transaction-payment-type"
},
"fields": {
"idempotencyKey": "your-unique-idempotency-key"
}
}
}
}
Custom refund reference
By default, the refund reference field is taken from interactionId of authorization transaction. If you need to customize the value of the refund reference, add a transaction custom field with key reference to the custom type with key ctp-payever-integration-transaction-payment-type. The addTransaction action will look like following:
{
"action": "addTransaction",
"transaction": {
"type": "Refund",
"amount": {
"currencyCode": "EUR",
"centAmount": 500
},
"state": "Initial",
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-transaction-payment-type"
},
"fields": {
"reference": "your-custom-refund-reference"
}
}
}
}
By default it uses transaction ID as the idempotency key when custom field with key idempotencyKey is not specified.
Follow these recommendations when using the idempotency key:
-
idempotencyKeymust be unique per request so that in case the request fails, it can be retried with the same key. - Generate idempotency keys using the version 4 (random) UUID type to prevent two API credentials under the same account from accessing each other's responses.
- Use exponential backoff
Refund requests for payment splits
To be able to trigger refund request for payment that was created with splits, you need to add a custom field with key splitReference to the transaction with custom type with key ctp-payever-integration-transaction-payment-type. The addTransaction action will look like following:
{
"action": "addTransaction",
"transaction": {
"type": "Refund",
"amount": {
"currencyCode": "EUR",
"centAmount": 16000
},
"state": "Initial",
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-transaction-payment-type"
},
"fields": {
"splitReference": {{unique-split-reference1}}
}
}
}
}
Follow these recommendations when using the split reference:
-
splitReferencemust be the same string that was sent in one of the splits in createPaymentV3Request.
Additional information
Don't add too many Refund transactions at once because API Extension endpoint has a time limit. By adding too many transactions at once, extension module will need more time to process all of them and this could lead to long requests and exceeding the time limit.
Further resources: payever refund API
Step 7: Cancel a payment
Cancel a payment
If you have authorised a payment but do not want to capture it, you need to make a Cancel request to release the funds back to the shopper.
If the payment has already been captured, you need to refund it instead.
Make an API call to cancel a payment.
Prerequisites:
It is required that the payment has one Authorization transaction with state Success.
From this transaction, the interactionId field is being used as paymentId for the payever cancel request.
Steps
To make a cancellation, add a transaction with type CancelAuthorization and state Initial to the commercetools payment.
{
"action": "addTransaction",
"transaction": {
"type": "CancelAuthorization",
"amount": {
"currencyCode": "EUR",
"centAmount": 1000
},
"state": "Initial"
}
}
Extension module will update the commercetools transaction with Success transaction state and interactionId field with value paymentId from the payever response:
{
"id": "a4504b99-d46e-484e-1344-ee4c3b6de1a2",
"type": "CancelAuthorization",
"amount": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 1000,
"fractionDigits": 2
},
"interactionId": "0946b9f4-4ac5-470e-963d-8504c7ef8faf",
"state": "Success"
}
Request/response between payever and extension module are stored in interfaceInteraction field of the payment with type cancelPayment.
The commercetools payment representation after a successful CancelAuthorization request:
{
"id": "ca068e31-c2f1-410a-912d-d12bf3c645b2",
"key": "14",
"amountPlanned": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 1000,
"fractionDigits": 2
},
"paymentMethodInfo": {
"paymentInterface": "ctp-payever-integration"
},
"transactions": [
{
"id": "98d62c56-9a72-4b96-8cb7-f9fe68181085",
"type": "Authorization",
"amount": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 1000,
"fractionDigits": 2
},
"interactionId": "0946b9f4-4ac5-470e-963d-8504c7ef8faf",
"state": "Success"
},
{
"id": "5d3e8fc1-bdb7-4e34-b3e9-8b34c3f60135",
"type": "CancelAuthorization",
"amount": {
"type": "centPrecision",
"currencyCode": "EUR",
"centAmount": 1000,
"fractionDigits": 2
},
"interactionId": "0946b9f4-4ac5-470e-963d-8504c7ef8faf",
"state": "Success"
}
],
"interfaceInteractions": [
{
"type": {
"typeId": "type",
"id": "5d93411a-9736-43ba-9f4d-5f14158427ba"
},
"fields": {
"createdAt": "2020-11-19T16:17:14.247Z",
"request": "{\"paymentId\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"amount\":\"10\"}",
"response":"{\"id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"status\":\"STATUS_CANCELLED\",\"merchant_name\":\"ANWR Media GmbH\",\"customer_name\":\"Thu Nguyen\",\"payment_type\":\"zinia_bnpl_de\",\"customer_email\":\"ndtthu@gmail.com\",\"created_at\":\"2023-06-16T07:09:32.000Z\",\"updated_at\":\"2023-06-16T07:16:33.000Z\",\"channel\":\"commercetools\",\"channel_type\":null,\"channel_source\":null,\"reference\":\"2f80c7e2\",\"amount\":10.00,\"total\":10.00,\"currency\":\"EUR\",\"delivery_fee\":0,\"payment_fee\":0,\"down_payment\":0,\"payment_details\":{\"birthday\":null,\"order_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"otp_id\":null,\"redirect_url\":\"https://linkup.demo.cf.zinia.com/0946b9f4-4ac5-470e-963d-8504c7ef8faf?documentCountry=DE\",\"expiration_time\":\"2023-06-16T07:19:33.633Z\",\"advertising_accepted\":true,\"conditions_accepted\":true,\"finalize_unique_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"receipt_unique_id\":null,\"reservation_unique_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"usage_text\":\"\",\"shop_user_session\":null},\"payment_details_array\":{\"birthday\":null,\"order_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"otp_id\":null,\"redirect_url\":\"https://linkup.demo.cf.zinia.com/0946b9f4-4ac5-470e-963d-8504c7ef8faf?documentCountry=DE\",\"expiration_time\":\"2023-06-16T07:19:33.633Z\",\"advertising_accepted\":true,\"conditions_accepted\":true,\"finalize_unique_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"receipt_unique_id\":null,\"reservation_unique_id\":\"0946b9f4-4ac5-470e-963d-8504c7ef8faf\",\"usage_text\":\"\",\"shop_user_session\":null},\"address\":{\"city\":\"Gescher\",\"country\":\"DE\",\"country_name\":\"DE\",\"email\":\"ndtthu@gmail.com\",\"first_name\":\"Thu\",\"last_name\":\"Nguyen\",\"phone\":\"+4915212341234\",\"salutation\":\"\",\"street\":\"On Campus 5\",\"zip_code\":\"48712\"},\"shipping_address\":{\"city\":\"Gescher\",\"country\":\"DE\",\"country_name\":\"DE\",\"first_name\":\"Thu\",\"last_name\":\"Nguyen\",\"salutation\":\"\",\"street\":\"On Campus 5\",\"zip_code\":\"48712\"}}",
"type": "cancelPayment"
}
}
]
}
Retry cancel requests
To be able to retry cancel requests in case of failure, you need to add a custom field with key idempotencyKey to the custom type with key ctp-payever-integration-transaction-payment-type. The addTransaction action will look like following:
{
"action": "addTransaction",
"transaction": {
"type": "CancelAuthorization",
"amount": {
"currencyCode": "EUR",
"centAmount": 500
},
"state": "Initial",
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-transaction-payment-type"
},
"fields": {
"idempotencyKey": "your-unique-idempotency-key"
}
}
}
}
Custom cancel reference
By default, the cancel reference field is taken from interactionId of authorization transaction. If you need to customize the value of the cancel reference, add a transaction custom field with key reference to the custom type with key ctp-payever-integration-transaction-payment-type. The addTransaction action will look like following:
{
"action": "addTransaction",
"transaction": {
"type": "CancelAuthorization",
"amount": {
"currencyCode": "EUR",
"centAmount": 500
},
"state": "Initial",
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-transaction-payment-type"
},
"fields": {
"reference": "your-custom-cancel-reference"
}
}
}
}
By default it uses transaction ID as the idempotency key when custom field with key idempotencyKey is not specified.
Follow these recommendations when using the idempotency key:
-
idempotencyKeymust be unique per request so that in case the request fails, it can be retried with the same key. - Generate idempotency keys using the version 4 (random) UUID type to prevent two API credentials under the same account from accessing each other's responses.
- Use exponential backoff when retrying.
Cancel requests for payment splits
To be able to trigger refund request for payment that was created with splits, you need to add a custom field with key splitReference to the transaction with custom type with key ctp-payever-integration-transaction-payment-type. The addTransaction action will look like following:
{
"action": "addTransaction",
"transaction": {
"type": "CancelAuthorization",
"amount": {
"currencyCode": "EUR",
"centAmount": 16000
},
"state": "Initial",
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-transaction-payment-type"
},
"fields": {
"splitReference": {{unique-split-reference1}}
}
}
}
}
Follow these recommendations when using the split reference:
-
splitReferencemust be the same string that was sent in one of the splits in createPaymentV3Request.
Further resources: payever cancel documentation
Metadata for commercetools transaction
In order to add some details to commercetools transaction please add a transaction custom field with key metadata for transaction with custom type with key ctp-payever-integration-transaction-payment-type. The addTransaction action will look like following:
{
"action": "addTransaction",
"transaction": {
"type": "Charge",
"amount": {
"currencyCode": "EUR",
"centAmount": 500
},
"state": "Initial",
"custom": {
"type": {
"typeId": "type",
"key": "ctp-payever-integration-transaction-payment-type"
},
"fields": {
"metadata": "your-additional-payment-details-json"
}
}
}
}
Step 8: Subscriptions
Our integration uses Subscriptions for Messages and Notifications. Subscriptions are used to trigger an asynchronous background process in response to an event on commercetools Composable Commerce.
In order to activate the subscriptions we recommend to enable messages in the project messages (Settings -> Developer settings -> Project messages). Meanwhile our integration has a Subscription set up with Azure Service Bus and we are being subscribed on these 3 order messages:
- Order Shipment State Changed - is triggred to capture a payever payment
- Return Info Added - is triggred to refundthe payever payment;
- Order State Changed - is triggred to cancel the payver payment;
Capture a payever payment
In order to shipping goods (capture) a payment fully (or rest amount available to capturing) it is nesessery to go to order page in the merchant center of Commercetools and change Shipment status to Shipped or Delivered.
Refund the payever payment
If you want to return the funds to your shopper, for example if they returned an item, you need to open order page in the merchant center of Commercetools -> Returns and Create return. There is needed to select quantity of items that are going to be returned and click save button at the end.
Cancel the payever payment
If you have authorised a payment but do not want to capture it, you need to make a Cancel request to release the funds back to the shopper.
If the payment has already been captured, you need to refund it instead.
To make a cancellation, go to the order page in the merchant center of Commercetools and change Order status to Cancelled.