You can add PayTo to your existing integration. The following instructions show only what you must add to your integration specifically for PayTo.
If an instruction on this page corresponds with a step in the main integration guide, it includes a link to corresponding step of the main integration guide.
Requirements
Requirement | Description | |
---|---|---|
Integration type | Make sure that you have an existing API-only integration. This page includes only instructions to add PayTo to your existing integration. |
|
Checkout API | Make sure that you use Checkout API v70 or later. | |
Action handling | Make sure that your existing integration is set up to handle the additional action. action.type : await. |
|
Setup steps | Before you begin, add PayTo in your Customer Area. |
Get PayTo as an available payment method
When you make the /paymentMethods to get available payment methods, specify the following so that PayTo is included in the response.
Parameter | Values |
---|---|
countryCode | AU |
amount.currency | AUD |
shopperReference | Optional. Your shopper's unique ID to retrieve their stored payment methods. |
Build your payment form
We provide the logo for PayTo that you can download.
Include PayTo in the list of available payment methods. You do not need to collect any information from the shopper in your payment form.
Add additional parameters to your /payments request
When you make a payment, add the following parameters:
Parameter | Required | Description | |
---|---|---|---|
storePaymentMethod |
Set to true to store Payment details for recurring payments. | ||
recurringProcessingModel |
Required for recurring or stored Payments. | ||
shopperStatement |
Used in the case of One-time payments where the “mandate” object is omitted. | ||
paymentMethod.type |
![]() |
payto | |
paymentMethod.shopperAccountIdentifier |
![]() |
The shopper's banking details or PayID reference, used to complete the payment. Possible values. 1 | |
shopperName.firstName |
![]() |
The shopper's first name. | |
shopperName.lastName |
![]() |
The shopper's last name. | |
mandate.frequency |
![]() |
The frequency with which a shopper should be charged. Possible values: adhoc, daily, weekly, biWeekly, monthly, quarterly, halfYearly, yearly. adhoc: Suitable for Card On File and Unscheduled Card On File recurring processing models. daily, weekly, biWeekly, monthly, quarterly, halfYearly, yearly: Suitable for Subscription recurring processing model. |
|
mandate.startsAt |
Start date of the billing plan, in YYYY-MM-DD format. By default, the transaction date. | ||
mandate.endsAt |
![]() |
End date of the billing plan, in YYYY-MM-DD format. | |
mandate.amount |
![]() |
The billing amount (in minor units) of the recurring transactions. 1 to 1000000000. | |
mandate.amountRule |
![]() |
The limitation rule of the billing amount. Possible values: max: The transaction amount can not exceed the amount. exact: The transaction amount should be the same as the amount. |
|
mandate.count |
The number of transactions that can be performed within the given frequency. Conditions: If the frequency is different than adhoc the count has to be provided and should be >= 1If frequency is adhoc the count can be omitted or will represent the total number of payments that can be done. |
||
mandate.remarks |
![]() |
The agreement description shown to the shopper up to 140 chars. | |
lineItems.quantity |
From 0 to 9999. | ||
lineItems.sku |
Up to 200 chars. Note that this field is only available from v70 onwards. | ||
lineItems.description |
Used to display the payment statement description to the shopper. Up to 280 chars. If multiple items, the item descriptions will be appended with a "," separator. |
||
lineItems.amountIncludingTax |
From 1 to 100000000. | ||
lineItems.itemCategory |
Up to 200 chars. |
1 Possible sources for the value of shopperAccountIdentifier
, indicating validation requirements:
- BSB-AccountNumber: ^\d{6}-[ -~]{1,28}$
- PayID Email: ^(?:[a-z0-9!#$%&'+\/=?^_`{|}~-]+(?:.[a-z0-9!#$%&'+\/=?^_`{|}~-]+)@(?:[a-z0-9] (?:[a-z0-9-][a-z0-9])?.)+[a-z0-9] (?:[a-z0-9-]*[a-z0-9])?)$
- PayID Phone Number: ^+[0-9]{1,3}-[1-9]{1,1}[0-9]{1,29}$
- PayID ABN: ^((\d{9})|(\d{11}))$
- PayID Organisation Identifier: ^[!-@[-~][ -@[-~]{0,254}[!-@[-~]$
Subscription setup
The request below will create a weekly subscription agreement where the weekly payment can be up to $90.
amount.value
: The first immediate payment will be of $30 (once the agreement is accepted by the shopper).
mandate.frequency
: Create a weekly subscription agreement.
mandate.amountRule
: The payment can be up to a maximum of mandate.amount $90.
mandate.count
: Set to only 1 payment per week.
mandate.endsAt
: The agreement will end the 31st of December 2025.
mandate.remarks
: The description shown to the user in the agreement.
curl https://checkout-test.adyen.com/v71/payments \ -H "x-API-key: ADYEN_API_KEY" \ -H "content-type: application/json" \ -d '{ "amount": { "currency": "INR", "value": 15100 }, "countryCode": "IN", "merchantAccount": "ADYEN_MERCHANT_ACCOUNT", "reference": "YOUR_ORDER_NUMBER", "paymentMethod": { "type": "upi_intent", "appId": "gpay" }, "returnUrl": "https://your-company.com/checkout?shopperOrder=12xy.." }'
The /payments response contains an action
object with the information needed to redirect the shopper.
curl https://checkout-test.adyen.com/v71/payments \ -H "x-API-key: ADYEN_API_KEY" \ -H "content-type: application/json" \ -d '{ "resultCode": "Pending", "action": { "paymentData": "Ab02....M9tFK", "paymentMethodType": "payto", "mandate": { "frequency":"weekly", "endsAt":"2025-12-31", "amount":"9000", "amountRule":"max", "count":"1", "remarks":"Agreement description" }, "name": "John Doe", "payID": "PayID@domain.com", "payee": "Dummy Legal Name", "type": "await" }, "paymentData": "Ab02....M9tFK" }'
Because PayTo is an asynchronous payment method, from this point, the shopper will receive a notification from their bank (via sms, email or directly from their banking app) in order to authorize or decline the agreement.
By listening to the AUTHORISATION event webhook you will get the outcome of the payment as well as the id
for the recurringDetailReference
.
Subsequent payments
Using the id
from the AUTHORISATION event, subsequent /payments requests may be initiated within the confines set out in the original mandate.
curl https://checkout-test.adyen.com/v71/payments \ -H "x-API-key: ADYEN_API_KEY" \ -H "content-type: application/json" \ -d '{ "amount": { "currency": "AUD", "value": 3000 }, "reference": "[YOUR MERCHANT REFERENCE]", "paymentMethod": { "type": "payto", "recurringDetailReference":"DSMSTN8J98MKDM92" }, "shopperReference": "[YOUR UNIQUE CUSTOMER ID]", "shopperInteraction": "ContAuth", "merchantAccount": "TestMerchant" }'
This is the response for the subsequent payment:
curl https://checkout-test.adyen.com/v71/payments \ -H "x-API-key: ADYEN_API_KEY" \ -H "content-type: application/json" \ -d '{ "resultCode": "Pending", "action": { "paymentData": "Ab02....M9tFK", "paymentMethodType": "payto", "type": "await" }, "paymentData": "Ab02....M9tFK" }'
One-time payments
One-time payments follow the same flow as subscriptions, but the mandate
parameter is optional in the /payments request, because it does not have to provide facility for subsequent payments.
curl https://checkout-test.adyen.com/v71/payments \ -H "x-API-key: ADYEN_API_KEY" \ -H "content-type: application/json" \ -d '{ "merchantAccount": "[YOUR MERCHANT ACCOUNT]", "reference": "[YOUR REFERENCE]", "amount": { "currency": "AUD", "value": 3000 // Amount to charge to the shopper once the agreement is accepted }, "paymentMethod": { "type": "payto", "shopperAccountIdentifier":"PayID@domain.com" // This field can be a PayID or a BBan (BSB + Account Number) please validate the field with the possible regexp rules }, "countryCode":"AU", "shopperName": { "firstName": "John", "lastName": "Doe" }, "shopperReference": "" // Optional field in order to modify the description of the agreement sent to the shopper "returnUrl":"[YOUR RETURN URL]" }'
This is the response for the one-time payment:
curl https://checkout-test.adyen.com/v71/payments \ -H "x-API-key: ADYEN_API_KEY" \ -H "content-type: application/json" \ -d '{ "resultCode": "Pending", "action": { "paymentData": "Ab02....M9tFK", "paymentMethodType": "payto", "mandate": { "frequency":"adhoc", "endsAt":"2025-01-31", // The end date will be set at Day+1 of the day when request is sent "amount":"3000", // The amount will be equal to the amount sent in the payment request "amountRule":"exact", "count":"1", "remarks":"One time payment" // The default value will be set to "One time payment" to modify it, you can provide the shopperStatement field in your paymentRequest }, "name": "John Doe", "payID": "PayID@domain.com", "payee": "Dummy Legal Name", // This field is the merchant legal name registered with Adyen "type": "await" }, "paymentData": "Ab02....M9tFK" }'
Required Webhook Notifications
The following webhook notifications indicate the status of the transaction.
OFFER_CLOSED
This notification will be returned when the agreement failed or is canceled by the user.
In this case, the refusalReasonRaw
will be included in the additionalData
object in the format errorCode:errorDescription
. The contents of refusalReasonRaw
will provide details about the reason for the failure or cancellation. Process the refusalReasonRaw
to obtain more information about the decline or cancellation reason.
AUTHORISATION
You will receive this notification for a payment on an accepted agreement, the payment outcome could be authorized or rejected.
In case the payment fails due to an error, you can consume the refusalReasonRaw
that is returned in the additionalData
object of your notification to get additional information about the reason for the payment being refused.
REFUND
When the refund is successfully received, the outcome will most likely succeed unless you receive a REFUND_FAILED notification.
REFUND_FAILED
Because refunds are asynchronous events, the outcome might fail due to unexpected reasons. In such cases you will receive a REFUND_FAILED notification.
RECURRING_CONTRACT
Contains the token in the payload of the notification sent to you in the pspReference
parameter.
DISABLE_RECURRING
When an agreement arrives to term, or is canceled (by you or the shopper), you will receive a DISABLE_RECURRING notification to keep you informed about a token deletion.
Token lifecycle webhooks are also supported.
Handle the additional action
You must handle the additional action for PayTo.
The action.type
is await.
Test and go live
To test, use the shopperAccountIdentifier
with the following emails to simulate testing scenarios:
Type | shopperAccountIdentifier | Result | Description |
---|---|---|---|
Agreement | [Any valid input] | Authorised | Successful payment. |
expire@adyen-test.com | OFFER_CLOSED | The Agreement has expired, please request your shopper to pay again. | |
debtor_account_type_not_supported@adyen-test.com | OFFER_CLOSED | The agreement has been refused. | |
Payment | [Any valid input] | Authorised | Successful payment. |
insufficient_funds@adyen-test.com | Refused | Insufficient Funds | |
debtor_account_closed@adyen-test.com | Refused | The Shopper account is closed. | |
financial_infrastructure_unavailable@adyen-test.com | Error | NPP is unable to process the payment due to back office issues or outage. |