One-click payments: saving your customer's card

From Barion Documentation
Revision as of 11:36, 9 August 2024 by [email protected] (talk | contribs) (first iteration of new page converted from .dev markdoc)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

One-click payments: saving your customer's card

Learn how to register a token to represent a customer’s payment instrument (bank card or Barion Wallet) during a payment, so you won’t need to redirect the customer to the Barion Smart Gateway for later payments to enter their payment instrument details.

The Barion ecosystem calls this payment scenario “one-click payment”.

It’s one of the “recurring payment” scenarios; an umbrella term for payment scenarios where a payment instrument’s payment data is registered with Barion to bypass the Barion Smart Gateway during later payments using that payment instrument.

You’ll be

  1. generating, storing, and passing a unique token to represent the customer’s payment instrument to the payment start API call;
  2. storing (and usually displaying to the customer) the description of the payment instrument that you’ve registered for later reuse;
  3. passing the registered token in later payments using the same payment instrument, and, if necessary, performing the customer’s 3DS v2 authentication using the Barion off-site authentication library.

Prerequisites

  1. a Barion Wallet with a balance in the currency of the payment
  2. an active Barion shop
  3. an approved request to Barion to allow recurring payment scenarios in the Barion shop

Enable recurring payment scenarios for your Barion shop

Recurring payments are enabled by default in the Barion Sandbox environment.

  1. Make sure that your webshop meets the following criteria for recurring payment scenarios:
    • your customers are prompted to explicitly consent before you trigger the payment scenario
    • your customers are informed about how they can change their mind about the scenario

      Read the full list of Barion's criteria for enabling recurring payments for a Barion shop here().

    • Ask Barion customer support to enable recurring payments for your Barion shop, using the Customer service tab in your Barion Wallet, or the "Other>Help" screen in the Barion app.

Integrate Barion’s off-site authentication

Note that customers won’t be challenged to authenticate themselves during a subsequent payment if the payment instrument that they save during the initial payment is their Barion Wallet balance.

The point of saving a payment instrument is for your customer not having to be redirected to the Barion Smart Gateway for subsequent payments using the registered payment instrument.

If the customer is challenged to authenticate themselves during a subsequent payment, and they have to go back to the Barion Gateway to do it, this defeats the purpose of saving their card. That’s where Barion’s off-site auth library comes in.

Once a customer’s card has been registered during the initial payment, Barion’s off-site auth library will let you display the 3DS challenge without redirecting your customer during subsequent payments.

  1. Include the following CSS and JavaScript files in your site’s head:

    <link href="https://secure.barion.com/static/barion.offsitegw.min.css" rel="stylesheet">
    <script src="https://secure.barion.com/static/barion.offsitegw.min.js"></script>
  2. Define an object named configuration in another JavaScript file associated with your site, with the following event handlers to handle the success or failure events returned by the authenticate method of the Barion off-site authentication library:

    • onAuthenticationSucceeded
    • onAuthenticationFailed
  3. Pass the configuration object to the authentication library:

    const gw = new Barion.OffsiteGw(configuration);
  4. Initialize the library when your site’s DOM is loaded:

    document.addEventListener("DOMContentLoaded", function () {
        gw.init();
    });

Create a token to represent the customer’s payment instrument

Note that you need to request and receive consent from the customer in a way that meets Barion’s relevant requirements, before you can register their payment instrument with Barion.

When your customer wants to save the payment instrument (bank card (used directly or as a card saved in an Apple Pay or Google Pay digital wallet), or Barion Wallet) of a payment, do the following.

  1. Make a call to the Payment start API endpoint with the following three extra properties:

    • InitiateRecurrence: true

    • RecurrenceId: <the unique token that you generate and save for the customer’s payment instrument> > Note that multiple shops can share the same token – get in touch with Barion Merchant Helpdesk for details.

    • RecurrenceType: OneClickPayment

      Note that with the RecurrenceType property passed to the API call, the Barion Smart Gateway will only display to the customer the payment method options that can be tokenized. For example, the bank transfer payment method isn’t available as a token scenario.

    If the endpoint responds with the RecurringPaymentNotAllowed error code, get in touch with Barion customer support to enable token payments for your shop.

  2. Redirect the customer to the GatewayURL parameter returned by the payment start endpoint.

  3. Process the payment callback as usual.

    A generic Payment/Start API endpoint response:

    {
         "PaymentId": "ee849878c554ef118c0c001dd8b71cc5",
         "PaymentRequestId": "DEV-TEST-615",
         "Status": "Prepared",
         "QRUrl": "https://api.test.barion.com/qr/generate?paymentId=ee849878-c554-ef11-8c0c-001dd8b71cc5&size=Large",
         "Transactions": [
             {
                "POSTransactionId": "DEV-TEST-01-01",
    "TransactionId": "ef849878c554ef118c0c001dd8b71cc5",
    "Status": "Prepared",
    "Currency": "EUR",
    "TransactionTime": "0001-01-01T00:00:00",
    "RelatedId": null
    }
    ],
    "RecurrenceResult": "None",
    "ThreeDSAuthClientData": null,
    "GatewayUrl": "https://secure.test.barion.com/Pay?Id=ee849878c554ef118c0c001dd8b71cc5",
    "RedirectUrl": "https://example.com/?paymentId=ee849878c554ef118c0c001dd8b71cc5",
    "CallbackUrl": "",
    "TraceId": null,
    "Errors": []
    }</snytaxhighlight>
    <blockquote><p>If the initial payment fails, the registration of the token also automatically fails.</p></blockquote></li>
    <li><p>Query [[05-api-reference/01-payment-resource/01-payment-state|the payment state endpoint]].</p>
    <p>Pass the query the <code>PaymentId</code> returned by the payment start endpoint as a query parameter, and your Barion shop’s POSkey as <code>x-pos-key</code> in the query header.</p></li>
    <li><p>Store the <code>FundingSource</code> and <code>FundingInformation</code> values in the payment state endpoint response.</p>
    <p>A generic payment/paymentstate API endpoint response:</p>
    <syntaxhighlight lang="json">
    {
        "PaymentId": [the payment ID generated for the transaction],
        "PaymentRequestId": "DEV-TEST-266",
        "OrderNumber": "Order_01",
        "POSId": [the Barion shop's unique identifier],
        "POSName": "sampleName",
        "POSOwnerEmail": "[email protected]",
        "POSOwnerCountry": "HU",
        "Status": "Succeeded",
        "PaymentType": "Immediate",
        "FundingSource": "BankCard",
        "RecurrenceType": null,
        "TraceId": null,
        "FundingInformation": {
            "BankCard": {
                "MaskedPan": "5559",
                "BankCardType": "Visa",
                "ValidThruYear": "2026",
                "ValidThruMonth": "1"
            },
            "AuthorizationCode": "zpua9p",
            "ProcessResult": "Successful"
        },
        "AllowedFundingSources": [
            "All"
        ],
        "GuestCheckout": true,
        "CreatedAt": "2024-04-26T12:27:00.564Z",
        "ValidUntil": "2024-04-26T12:57:00.564Z",
        "CompletedAt": "2024-04-26T12:27:37.741Z",
        "ReservedUntil": null,
        "DelayedCaptureUntil": null,
        "Transactions": [
            {
                "TransactionId": [the generated GUID for the transaction],
                "POSTransactionId": "DEV-TEST-01-01",
                "TransactionTime": "2024-04-26T12:27:00.579Z",
                "Total": 50.00,
                "Currency": "EUR",
                "Payer": {
                    "Name": {
                        "LoginName": "[email protected]",
                       "FirstName": null,
                        "LastName": null,
                        "OrganizationName": null
                    },
                    "Email": "[email protected]"
                },
                "Payee": {
                    "Name": {
                        "LoginName": "[email protected]",
                        "FirstName": null,
                        "LastName": null,
                        "OrganizationName": "Demo Merchant"
                    },
                   "Email": "[email protected]"
                },
                "Comment": "Test transaction",
                "Status": "Succeeded",
                "TransactionType": "CardPayment",
                "Items": [
                    {
                        "Name": "Nada",
                        "Description": "Zilch",
                        "Quantity": 1.00,
                        "Unit": "db",
                        "UnitPrice": 100.00,
                        "ItemTotal": 100.00,
                        "SKU": "SM-01"
                    }
                ],
               "RelatedId": null,
                "POSId": [sample ID],
                "PaymentId": [sample ID]
            },
            {
                "TransactionId": [the generated GUID for the transaction],
                "POSTransactionId": null,
                "TransactionTime": "2024-04-26T12:27:00.643Z",
                "Total": 0.50,
                "Currency": "EUR",
                "Payer": {
                    "Name": {
                        "LoginName": "[email protected]",
                       "FirstName": "Gipsz",
                        "LastName": "Jakab",
                        "OrganizationName": null
                    },
                    "Email": "[email protected]"
                },
                "Payee": {
                    "Name": {
                        "LoginName": null,
                        "FirstName": null,
                        "LastName": null,
                        "OrganizationName": "Barion"
                    },
                    "Email": null
                },
                "Comment": null,
               "Status": "Succeeded",
                "TransactionType": "GatewayFee",
               "Items": [],
                "RelatedId": null,
                "POSId": [sample ID],
                "PaymentId": [sample ID]
            },
            {
                "TransactionId": [sample ID],
                "POSTransactionId": null,
                "TransactionTime": "2024-04-26T12:27:00.658Z",
                "Total": 0.50,
                "Currency": "EUR",
                "Payer": {
                    "Name": {
                        "LoginName": "[email protected]",
                        "FirstName": "Gipsz",
                        "LastName": "Jakab",
                        "OrganizationName": null
                    },
                    "Email": "[email protected]"
                },
               "Payee": {
                    "Name": {
                        "LoginName": null,
                        "FirstName": null,
                        "LastName": null,
                        "OrganizationName": "Barion"
                    },
                    "Email": null
                },
                "Comment": null,
                "Status": "Succeeded",
                "TransactionType": "CardProcessingFee",
                "Items": [],
                "RelatedId": null,
                "POSId": [sample ID],
                "PaymentId": [sample ID]
            }
        ],
        "Total": 50.00,
        "SuggestedLocale": "hu-HU",
        "FraudRiskScore": null,
        "RedirectUrl": "http://barion.com/?paymentId=[sample ID]",
        "CallbackUrl": null,
       "Currency": "EUR",
       "Errors": []
       }

    FundingSource and FundingInformation indicate the type of payment method and the description of the payment instrument that the customer has selected for the payment, and so the payment instrument that the RecurrenceId token will represent in future payments.

    This way, you’ll be able to display anonymized details of the saved payment instrument to your customers for future payments, so they can decide if they want to take advantage of the one-click payment option.

Use the registered token for later payments

When your customer consents to use an already-registered payment instrument, have your site do the following:

  1. Call the Payment start Barion API endpoint, and pass it:

    • the registered RecurrenceId,
    • RecurrenceType: OneClickPayment,
    • InitiateRecurrence: false, and
    • ChallengePreference: NoChallengeNeeded. This last parameter is to make sure that the customer will only need to perform 3DS authentication if the transaction’s Transaction Risk Analysis (TRA) score rquires it.

    Troubleshooting {% table %}

    • Error code

    • Description

    • InvalidRecurrenceId

    • The registered token was found to be invalid. Usually because the token’s registration had failed.

    • RecurringPaymentDenied

    • The Barion Wallet associated with the token had been deleted, suspended, or blocked since you registered the token.

    • InsufficientFunds

    • The Barion Wallet that the token represents doesn’t have enough funds to fulfill the charge.

    • OriginalPaymentWasntSuccessful

    • The payment where the bank card that the token represents was registered didn’t itself succeed, which invalidates the token.

    • InvalidCurrency

    • The Barion Wallet that the token represents doesn’t have a balance in the currency that the current payment requires.

    • CardExpired

    • The registered bank card had since expired. Re-initialize the original RecurrenceId to fix this – follow the steps here to do this.

    • TopUpFailed

    • This is an error code that isn’t relevant to the scenario, but which might still pop up.

      It’s usually accompanied by another, more specific error code.

    • ThreeDSNotEnabled

    • The issuer rejected the tokenized bank card because of a lack of Strong Customer Authentication.

    • InvalidUser

    • The source Barion Wallet doesn’t exist or isn’t fully activated.

    • UserCantMakeOutgoingTransaction

    • The source Barion Wallet is suspended or doesn’t exist.

    • CardError

    • An error occurred in either the 3DS authentication system or the bank system when processing the tokenized bank card.

      There can be several causes for this, from security settings to active limits on the card.

      You’ll need to reach out to the customer to troubleshoot the issue.

    • PingFailed

    • The bank or other third party didn’t respond to the request, so the Barion Payment API cancelled it. {% /table %}

  2. If the payment is flagged for 3DS authentication, call the Barion off-site authentication library’s authenticate method, passing it the ThreeDSAuthClientData string returned in the payment start API endpoint response:

    gw.authenticate(threeDsAuthClientData);

    It’s up to the issuer of the card used for the payment to determine whether they challenge the cardholder to verify their identity using 3DS authentication.

    Read more about the protocol in our dedicated guide.

  3. Call the payment complete Barion API endpoint, passing it the PaymentId returned by the Payment start call in step 1, to debit the registered payment instrument.