Skip to main content

Implement UPI on Adyen Integration v2.0

Zuora

Implement UPI on Adyen Integration v2.0

Support for the UPI payment method on Adyen can be requested through the Specialized Payment Connections service at an additional cost.

Overview

Unified Payments Interface (UPI) is an Indian instant payment system developed by the National Payments Corporation of India (NPCI). It enables users to link multiple bank accounts to a single mobile application, facilitating inter-bank transactions through a user-friendly process.

Zuora's Adyen Integration v2.0 supports UPI transactions in INR. To support UPI one-time and recurring payment flows, you can implement a hosted payment page through Payment Pages 2.0.

One-time payment flow

On the hosted payment page, your customers enter their Virtual Payment Address (VPA) and submit the payment through the Adyen payments request. The following table describes the workflows after Zuora receives a successful or failed response from the Adyen synchronous payment API.

Response Workflow

Successful response

  1. Zuora creates the following items:
    • A payment with Payment status = Processed and Gateway State = Submitted
    • A UPI payment method record
  2. A timer dialog is displayed, instructing your customers to open the UPI application on their mobile devices. In the UPI application, your customers complete the authorization within the time that you have configured when implementing your hosted payment page. 
  3. At the backend, Zuora listens to Adyen's webhook events.
    • Based on the returned webhook event, the UPI payment results are returned to the callback function of the hosted payment page. You can implement your customized logic to handle success or failure cases. 
    • Zuora also updates Gateway State according to the returned webhook:
      • If AUTHORIZATION is true, Gateway State is set to Settled
      • If AUTHORIZATION is false or OFFER_CLOSED is true, Gateway State is set to FailedToSettle
    • If Zuora does not receive Adyen's webhook event before time is up, Zuora returns an error callback with the Payment_Status_Unknown error code. You are recommended to proactively query the transaction status to check whether it is Settled or FailedToSettle. You can use the Retrieve a payment API operation and pass in the payment ID or payment method ID returned in the callback to query the status.

Failed response

Zuora throws an error on the hosted payment page with the error response message received from Adyen.

The created UPI payment method can be retrieved through the Zuora UI and API operations. In the Electronic Payment Methods section of the customer account page, you can also retrieve the token information described in the following table. Token ID and Second Token ID will be used in subsequent recurring payments.

Zuora UI field Value
Token ID shopperReference
Second Token ID ShopperDetailReference
Third Token ID mandate ID

After a payment is processed, the Reference ID field is populated with a UUID and mapped to pspReference. If you want Reference ID to be populated with the payment number mapped to the merchantReference field in Adyen, submit a ticket at Zuora Global Support.

Recurring payments flow

As regulation requires, a pre-debit notification per invoice must be sent to the UPI users before collecting the recurring payments. To support this requirement, Zuora immediately sends the pre-debit notification request to Adyen once the invoice is posted, if all of the following conditions are met.

Conditions for triggering pre-debit notification requests

  • The invoice has an outstanding balance.
  • The type of the payment method is UPI.
  • The type of the gateway instance is Adyen Integration v2.0 
  • The transaction currency is INR.
  • One of the following conditions regarding pre-debit notification reference is true:
    • No pre-debit notification has been successfully triggered for this invoice, and no pre-debit notification reference is stored in Zuora.
    • A pre-debit notification reference exists but has already been used for a processed payment. For example, an invoice is posted, and a pre-debit notification is sent. The recurring payment is processed successfully. Later, a refund is issued for this payment, reopening the invoice balance. Zuora's scheduled pre-debit notification retry picks up the invoice and sends another pre-debit notification.

Successful requests

Zuora sends the notifyShopper field in the request to Adyen for each invoice. Adyen synchronously returns the notificationReference field for successful requests, which will be used for the upcoming recurring payments. Zuora stores notificationReference and associates it with the invoice, processing the payment through the scheduled payment run. 

Your customers can make a recurring UPI payment in INR through Adyen under the allowed maximum amount configured for the mandate when implementing your hosted payment page. If the recurring payment amount is greater than the maximum allowed amount, additional authentication is required and you need to handle it outside Zuora.

Retries of failed requests

If the pre-debit notification request fails, no notificationReference is received from Adyen. Zuora retries the request using the following logic if the invoice meets the conditions in Conditions for triggering pre-debit notification requests:

  • If the gateway's notification API supports idempotency, Zuora retries sending the request immediately.
  • Zuora also retries the request at 09:30 AM IST (08:00 PM PST) and 11:30 AM IST (10:00 PM PST). By default, Zuora retries the request up to 23 days after the initial pre-debit notification attempt.

Manual initiation of the request

If you want to manually trigger the pre-debit notification, instead of waiting for the auto-retries, you can use the Trigger a pre-debit notification API operation. The invoice must also meet the conditions in Conditions for triggering pre-debit notification requests.

Mandate cancellation

If the mandate is canceled on your end, you can close the UPI payment method in Zuora by using the Delete a payment method REST API operation. If the mandate is canceled through the UPI application, Adyen notifies Zuora through Adyen's DISABLE_RECURRING webhook event, prompting Zuora to close the payment method.

Supported and unsupported features

The following table lists the supported and unsupported operations and features for UPI on Adyen Integration v2.0.

Supported Unsupported
  • One-time payment processing
  • Recurring payment processing
  • Standalone payment method validation
  • Payment method creation without making a one-time payment
  • Referenced refund
  • Real-Time Reconciliation
  • Support idempotency for retrying the following transaction requests:
    • Recurring payment 
    • Refund
  • Payment cancel (void)
  • Non-referenced refund
  • Batch Gateway Reconciliation
  • Delayed Capture
  • Stored Credential Transactions framework and the sharing NTI feature
  • Creation of UPI payment method through UI or API operation
  • Asynchronous Payment Statuses

Overall implementation procedure 

Overall, complete the following steps to implement a UPI payment flow to support one-time or recurring payments:

  1. Prepare for the integration.
  2. Set up a Payment Page 2.0.
  3. Request a signature from Zuora for the payment page.
  4. Set up your client code to integrate the payment page to your web page.
  5. Implement the callback response

You can find detailed instructions in the following sections.

Step 1. Prepare for the integration

Before implementing the UPI payment method on Adyen, ensure that all prerequisites outlined in the following sections are fulfilled.

UPI enablement and configuration

  • Ensure you have requested support for UPI on Adyen Integration v2.0 through the Specialized Payment Connections service.
  • Complete the following steps to activate the UPI payment method type on your tenant:
    1. Click your username in the upper right and navigate to Settings > Payments > Payment Method.
    2. Click Edit at the bottom of the page.
    3. Select UPI and click Save.

Adyen gateway instance configuration

To configure an Adyen gateway instance for processing UPI transactions, follow the instructions in Set up and configure an Adyen Integration v2.0 gateway instance.

In particular, you can skip the following requirements and settings as they do not apply to UPI transactions.

Prerequisites

The last two prerequisites do not apply to UPI.

  • The setting for recurring fields in the API response must be enabled…(See this article for a full description)
  • To ensure the network transaction ID (NTI) is returned...(See this article for a full description)

Credentials

  • Merchant Account for Payouts User Account
  • API Key for Payouts User Account
  • Merchant Account for Review & Confirm Payouts User Account
  • API Key for Review & Confirm Payouts User Account

Rules

  • Enable gateway reconciliation
  • Reconciliation Username
  • Reconciliation Password
  • Enable Level 2 Processing
  • Enable Level 3 Processing
  • ShipFrom Postal Code API Name
  • ProductCode Custom Field API Name
  • CommodityCode Custom Field API Name
  • Skip Risk Rules
  • Soft Descriptor
  • Submit Card Payments with RecurringDetailReference
  • Tokenize payment method

Additional Metadata

UPI does not support Additional Metadata.

For the following settings, specific values are passed to the gateway, regardless of the values configured in these settings in the UI.

Setting Value passed to Adyen

Shopper Interaction

  • For one-time payments: Ecommerce
  • For recurring payments: ContAuth

There is no way to override these values.

Recurring Processing Model

Subscription

If you want to override it, use the param_gwOptions_recurringProcessingModel gateway options field.

For the Auto-capture IP Address setting, enable it to ensure that the IP address is always included in your request as passing the IP address is required for Adyen UPI on-session transactions. The following list describes the priority of passing in the IP address:

  • If the IP address is provided through the gwOptions_shopperIP gateway options field, this value is used regardless of the Auto-capture IP Address setting.
  • If the gwOptions_shopperIP field is not specified and the Auto-capture IP Address setting is enabled, the browser's IP address is automatically included in the request.

Enablement of zero-amount validation

Contact Zuora to enable zero-amount validation by submitting a support ticket at Zuora Global Support. Include your tenant ID in your request.

Real-Time Reconciliation setup

To process UPI transactions, you must enable Real-Time Reconciliation. Follow the instructions in Enable and configure Real-Time Reconciliation for Adyen Integration v2.0.

Settings required for payment flow implementation

Adyen setting

To process recurring payments, make sure the 3DS2 Additional Fields setting is turned on in Adyen. The pspReference field will be included in the response returned from Adyen to Zuora.

Adyen's setting for supporting recurring payments

Zuora setting

Step 2. Create and configure a UPI payment page 

Complete the following steps to create and configure a UPI payment page:

  1. In Zuora UI, navigate to Settings > Payments, and click Setup Payment Page and Payment Link.
  2. On the Payment Pages tab page, configure the tenant-level settings for the hosted payment page.
  3. In the Type dropdown list, select UPI.
  4. Click Create New Hosted Page.
  5. In the Basic Information section, specify the following fields:
    Field Description

    Page Name

    Enter a name for your hosted payment page. This name is used to identify your payment page in Zuora. It is different from the title displayed on the payment page. You can specify the title in the Page Title field in the Page Configuration section.

    Hosted Domain

    Enter the domain address from which your payment page is served. This domain also hosts your callback page. The value must be in the format: https://www.domain.com.

    Zuora validates this field for you. If the validation fails, an error message is displayed on the payment page. Note that the Overlay Hosted Page mode does not support the hosted domain validation.

    If you want your hosted payment pages and callback pages to reside in the subdomain of the hosted domain, enable the tenant-level Allow Subdomain Callback for Hosted Pages setting.

    Callback Path

    Enter the path on which the callback page file resides. Zuora appends this to the Hosted Domain entry to create the full URL to which the callback is sent. Specify a value in the format: /app/callback_file.jsp. The file extension, such as .jsp or .php, is not required. However, the callback path must begin with a forward slash character ( / ).

    The Callback Path is only required for the advanced implementation option, which uses the inline style form with an external submit button. This setting is ignored for the basic setup, which uses the overlay form or the inline form with the submit button inside.

  6. In the Default Payment Gateway field of the Payment Gateway section, click and select an Adyen Integration v2.0 instance. Note that Zuora does not validate this setting. You can override this default gateway in your request by specifying a gateway through the paymentGateway client parameter.
  7. In the Page Configuration section, complete the field configuration.
    Field Description

    Page Title

    Enter a title for the hosted payment page. Select Display to display the Page Title on this payment page.

    Page Description

    Enter the description of the payment page. Select Display to display the Page Description on this payment page.

    VPA

    A required field for end-customers to enter a Virtual Payment Address to securely complete payments.

    Submit Button

    Enter the label to appear on the submit button. This label is applied only if the button is on the hosted payment page. The submitEnabled client parameter controls the placement of the submit button. See Client Parameters for Payment Pages 2.0 for details.

    Client-Side Validation

    Select Enable client-side validation to check the required fields for values.

    If the client-side validation is enabled, you can specify a custom error message for missing required fields in the Error Message field. Use "#fieldName" to include the missing field name in the error message. For example, "Please enter a valid #fieldName to continue.”

    CSS

    Enter the custom CSS code for your page. You can review the CSS ID and class names by using View Source or Inspect Element in Firefox or Chrome on the preview page of this payment page. For example, you can customize the style and format of the field label and the error message, as well as the error message texts. However, implementing customized JavaScript is not allowed for security reasons.

    Note that the UPI timer window designed by Zuora cannot be altered.

  8. Click Generate and Save Page.

Subsequently, you can preview the form

Step 3. Request a signature for the Payment Page

Follow the instructions in Request a signature for the Payment Page from Zuora. Because the Client-side HPM Parameter Validation feature is enabled, Zuora will validate the additional fields in the request by comparing them with the values specified in the digital signature.

Here are two request examples for the Generate RSA signature REST API operation.

{
    "uri":"https://sandbox.na.zuora.com/apps/Pu...tedPageLite.do",
    "method":"POST",
    "pageId":"test808145b3bf9d0145b3c6812b0008",
    "paymentGateway":"Adyen",
    "authroizationAmount":"100",
    "currency":"INR",
    "accountId":"test808145b3bf9d0145b3c6812b0008"
}
{
    "uri":"https://sandbox.na.zuora.com/apps/Pu...tedPageLite.do",
    "method":"POST",
    "pageId":"test808145b3bf9d0145b3c6812b0008",
    "paymentGateway":"Adyen",
    "accountId":"test808145b3bf9d0145b3c6812b0008"
}

Step 4. Set up your client code

Follow the instructions in Integrate Payment Pages 2.0. When rendering the Payment Page form, specify the following required parameters in the Z.render or Z.renderWithErrorHandler function. For other optional parameters, see Client Parameters for Payment Pages 2.0.

Required parameters

Required Parameter Description

field_upiTimerWindow

Type: integer

Default: 36 | Min: 5 | Max: 36

The timer window allows end-customers to complete the payment. By default, this window is set to 36 minutes. To modify the minimum and maximum limits, submit a request at Zuora Global Support.

Once the timer expires, the timer dialog closes. It then takes up to an additional two minutes to retrieve the latest payment status information from Adyen.

doPayment

Type: boolean

Default: false

true indicates that the Payment Page will create a payment method as well as process the one-time payment transaction.

If it is false or not specified, the Payment Page will only create a payment method. 

To implement payment processing flows, set doPayment to true

To implement payment method validation and setup flows, set doPayment to false.

storePaymentMethod

Type: boolean

Default: true

true indicates that the payment method will be stored in Zuora and used in subsequent recurring payments.

false indicates that the payment method will not be stored in Zuora. End-customers need to be brought back on session to authenticate the payment.

field_accountId

Type: string

Example: 8a90e5e48f2eade6018f2ed19133003a

Zuora customer account ID. This account must be set up with the INR currency. The payment method will be created for this specified account.

authorizationAmount

Required for authorization amount processing

For payment processing flow, it is the amount of the one-time payment that will be sent to the gateway. 

For payment method validation flow, specify 0 for this field.

For more information about this parameter, see Client parameters for Payment Pages 2.0.

field_currency

Required for authorization amount processing

The currency of the one-time payment amount. Only INR is supported by Adyen UPI.  

For more information about this parameter, see Client parameters for Payment Pages 2.0.

documents

Required for invoice processing

An array of invoices to be paid in this transaction, containing the following fields:

  • type - The value must be invoice.
  • ref - The value must be the invoice number, such as INV0000001.

param_gwOptions_UpiMandateEnabled

Type: boolean

Default: false

To create a mandate and store the payment method in Zuora for processing subsequent recurring payments, specify true.

Otherwise, specify false. The payment method will not be stored in Zuora. End-customers need to be brought back on session to authenticate the payment.

param_gwOptions_UpiMandateAmount

See mandate.amount in Adyen's documentation.

param_gwOptions_UpiMandateAmountRule

Default: max

See mandate.amountRule in Adyen's documentation.

param_gwOptions_UpiMandateFrequency

Default: adhoc

See mandate.frequency in Adyen's documentation.

param_gwOptions_UpiMandateStartsAt

See mandate.startsAt in Adyen's documentation.

param_gwOptions_UpiMandateEndsAt

See mandate.endsAt in Adyen's documentation.

param_gwOptions_UpiMandateRemarks

The mandate message that will be passed to the end customer.

The shoppers see this message when they open the notification.

See mandate.remarks in Adyen's documentation.

param_gwOptions_UpiMandateBillingAttemptsRule

Default: after

See mandate.billingAttemptsRule in Adyen's documentation.

param_gwOptions_UpiMandateBillingDay

Default: 1

See mandate.billingDay in Adyen's documentation.

If you want to use a non-zero value in a payment method verification request, pass the param_gwOptions_additionalAmount Gateway Options field. It is mapped to Adyen's additionalAmount.value field and sent to Adyen. See Adyen's documentation for more information.

shopperEmail

If you want to include the shopper's email address in the request to the gateway, submit a ticket at Zuora Global Support to enable this feature. You can then use the param_gwOptions_shopperEmail Gateway Options field to pass in the shopper's email address. If param_gwOptions_shopperEmail is not provided, the shopperEmail field in the payment request is populated with the email information of the account specified through field_accountId, according to the following priority order, from highest to lowest:

  • BillTo work email
  • BillTo personal email
  • SoldTo work email
  • SoldTo personal email

In recurring payments and ad-hoc payments triggered from the Zuora UI or API operations, the shopperEmail field in the payment request is also populated in the preceding priority order.

shopperReference

The shopperReference field in the request to the gateway is populated with a UUID by default. If you want to use the Gateway Options field to override it, submit a ticket at Zuora Global Support. You can then use the param_gwOptions_shopperReference Gateway Options field to pass in a value. If param_gwOptions_shopperReference is not provided, shopperReference is populated in the following priority order, from highest to lowest:

  • Zuora account number associated with the account ID specified through field_accountId
  • UUID

In recurring payments and ad-hoc payments triggered from the Zuora UI or API operations, the shopperReference field in the payment request is populated with the account number of the account specified in field_accountId.

Example

Here is an example of the parameters for the payment flow for processing the first one-time and subsequent recurring payments:

var params = {
    field_upiTimerWindow:20,
    doPayment:"true",
    storePaymentMethod:"true",
    field_accountId:"testc0f87596f2f301759c29443622fa",
    documents:"[{"type":"invoice","ref":"INV00026338"}, {"type":"invoice","ref":"INV00026339"}]",
    param_gwOptions_UpiMandateEnabled:"true",
    param_gwOptions_UpiMandateAmount:100000,
    param_gwOptions_UpiMandateAmountRule:"max",
    param_gwOptions_UpiMandateFrequency:"adhoc",
    param_gwOptions_UpiMandateStartsAt:"2024-05-06",
    param_gwOptions_UpiMandateEndsAt:"2024-09-28",
    param_gwOptions_UpiMandateRemarks:"sample message",
    param_gwOptions_UpiMandateBillingAttemptsRule:"after",
    param_gwOptions_UpiMandateBillingDay:"1"
};

Step 5. Implement the callback response

See Advanced Integration of Payment Pages 2.0 for more information.