Skip to main content

Online payments

Affirm

Last updated: 14-Aug-2025

Overview

Affirm offers flexible financing options for your shoppers to pay over time, while also ensuring you to receive the full payment upfront.

This guide will detail how you can take payments with Affirm using Verifone’s eCommerce API.

Before you get started

Starting from scratch? Follow these steps to get started.

Collect your Verifone Credentials (environment variables)

  • Select an environment (Sandbox or Production)
    • Make sure to set up the base of the URL (environment) to be configurable for when you are ready to proceed to production.
  • Collect your Payment Provider Contract ID
    • The Payment Provider Contract (PPC) represents the merchant’s contract with their acquiring partner, including key details such as the Merchant ID.

Take payments with Affirm

Decide for REDIRECT or MODAL checkout flow mode

  • REDIRECT (default): Users are redirected to Affirm site, where they authenticate and go through the checkout flow. Once they complete checkout, they're returned to the merchant site.
  • MODAL: Users go through the Affirm flow in a modal window while remaining on merchant site. Modal checkout with the help of affirm.js will enable client-side callbacks so that merchant can do post checkout confirmation procedures on merchant site.

Define and add a merchant reference (Recommended)

Use the merchant_reference field to specify an alphanumeric ID of your choosing. Typically, this corresponds to an order number from your inventory management system or web platform, allowing you to easily reconcile transaction reports with your orders. 

For example: “Merchant_reference”: “Order-123456789”

Capture now

Default capture flow behavior is ‘true’ which means that authorization and capture is performed in one step (‘auto-capture’) by Verifone. If capture_now flag is set to ‘false’ while initiating the payment the capture has to be executed as a separate process after the authorization. See Capture an authorized Affirm payment.

Payments with Affirm in REDIRECT mode

Step 1: Create an Affirm Payment

Using the Initiate a Affirm payment API call, we can generate a URL for the customer to visit and pay with Affirm.

API Reference: https://verifone.cloud/api-catalog/verifone-ecommerce-api#tag/Ecom-Payments/operation/affirmInitTransaction

Request Method: POST

URL {environment}/api/v2/transactions/affirm

Headers:

x-vfi-api-idempotencyKey – unique UUID to identify the transaction

Body:

{
	"payment_provider_contract": "{{ppc}}",
	"merchant_reference": "Order Sale 123",
	"amount": 60000,
	"redirect_url": "https://verifone.cloud/",
	"cancel_url": "https://verifone.cloud/",
	"currency_code": "USD",
	"locale": {
		"country_code": "US"
	},
	"capture_now": true,
}

Response:

{
	"amount": 60000,
	"created_at": 1729047737.9813294,
	"merchant_reference": " Order Sale 123",
	"status": "INITIATED",
	"id": "a520d533-e56c-4751-b9da-e448e12a298f",
	"payment_url": "https://sandbox.affirm.com/products/checkout?public_api_key=UFM3YKEQ6FX62&checkout_ari=WNEU0OFHE7SU90AO&locale=en_US&country_code=USA",
	"processor": "AFFIRM",
	"payment_product": "AFFIRM",
	"payment_product_type": "Affirm"
}

Explanation of fields:

  • id - the ID of the transaction
  • payment_url - the URL which can be accessed from any browser. It should be used to redirect the shopper
    redirect_url – The URL the customer will be redirected back to after completing the payment successfully
  • cancel_url – The URL the customer will be redirect back to if the cancel button is selected in the top left corner
  • capture_now – whether ‘auto-capture’ or not. See Capture now

Save these details later for the next steps:

1. payment_url 

2. checkout_ari from payment_url

3. id (This the transaction ID)

Step 2: Redirect the customer to the payment URL

Redirect the customer to the payment_url from Step 1.

The customer will then need to authenticate with Affirm via a Mobile number or a Passkey.

See Affirm Checkout Dialog.

Step 3: Identify the returning customer

After completing the affirm payment, the customer will be posted to the redirect_url or cancel_url.

In the POST message made to your browser, Affirm will return the checkout_ari as checkout_token:

Identify the returning customer

Use the checkout_token returned here to match against the corresponding checkout_ari & id (transaction_id) received in Step 1.

Step 4: Query the transaction result with Read Transaction

Using the id (transaction id) from Step 1, perform a read Transaction call to know the transaction result.

API Reference: https://verifone.cloud/api-catalog/verifone-ecommerce-api#tag/Transaction/operation/readTransaction 

Request Method: GET

URL: {environment}/api/v2/transaction/{transaction_id}

Response:

{
	"id": "a520d533-e56c-4751-b9da-e448e12a298f",
	"amount": "600.00",
	"currency_code": "USD",
	"created_at": "2024-10-22T01:35:22.676Z",
	"country_code": "US",
	"shipping_information": {},
	"customer_details": {
		"billing": {},
		"shipping": {}
	},
	"merchant_reference": "Order 123456",
	"status": "SALE AUTHORISED",
	"processor_reference": "B3312-7BII",
	"cvv_present": false,
	"processor_payer_id": "8saASadmd2e12l3dsm",
	"dynamic_descriptor": "Order Sale",
	"shopper_interaction": "ecommerce",
	"merchant_id": "1234567",
	"payment_summary": {
		"captured_amount": "600.00"
	},
	"transaction_status": "AUTHORISED",
	"transaction_type": "SALE",
	"entity_id": "432dj44-c41b-4c9b-964e-9cbf9da729d9",
	"acquirer_merchant_id": "ASHQWIQQ222444"
}

With a transaction_status of AUTHORISED we know the payment was successfully completed by the customer.

Payments with Affirm in MODAL mode

Step 1: Create an Affirm Payment

Verifone performs the Affirm Direct Checkout internally and provides the data to let you launch the Affirm modal by calling Affirm Javascript  SDK to show checkout page.

Add the mode flag to the common request body (see REDIRECT part). Checkout Id and Public Api Key are now additional parts of the response.

API Reference: https://verifone.cloud/api-catalog/verifone-ecommerce-api#tag/Ecom-Payments/operation/affirmInitTransaction

Request Method: POST

URL: {{env}}/api/v2/transactions/affirm

Headers:

x-vfi-api-idempotencyKey – unique UUID to identify the transaction

Body:

{ …
	"mode": "MODAL"
}

Response:

{ …
	"checkoutId": "{{Checkout ID}}",
	"publicApiKey": "{{Public API Key}}",
}

Explanation of fields:

  • mode – when MODAL mode shall be used this flag must be set to “MODAL” to indicate the checkout flow type towards Verifone.
  • checkout_id – a unique identifier representing the Payment Host checkout ID. This value is available only in MODAL mode.
  • public_api_key – the merchant’s public api key. This value is available only in MODAL mode.

Save these details later for the next steps:

1. checkoutId

2. publicApiKey

Step 2: Initialize and open Affirm checkout page

Prepare the config object for Affirm Javascript library affirm.js to be used with initialization function.

Affirm API Reference:
https://docs.affirm.com/payments/docs/afjs-reference
https://docs.affirm.com/payments/docs/open-affirm-checkout
https://docs.affirm.com/payments/docs/modal-vs-redirect-checkout

var _affirm_config = {
public_api_key: public_key,
script: "https://cdn1-sandbox.affirm.com/js/v2/affirm.js"
}

Explanation of fields:

Initiate the checkout process by calling ‘affirm.checkout(checkoutObject)’ with Checkout object: 

var checkoutObject = {
	"checkoutAri": checkoutId,
	"metadata": {
		"mode": "modal"
	}
}

Explanation of fields:

  • checkoutAri – a unique identifier representing the Payment Host checkout ID received in Step 1.
  • mode – indicates the checkout flow type MODAL towards Affirm.

Optional create callback functions to receive the feedback of the checkout process and to handle the events:

var callbacks = {
	onFail: function(error) {
	// Error handling
	},
	onSuccess: function(checkout) {
	// Success procedures
		},
	onOpen: function(token) {
	// Initialization successful
	},
	onValidationError: function(checkout_validation_error) {
	// Validation error handling
	}
}

Now call ‘affirm.checkout.open(callbacks)’ to open the Affirm checkout portal. See Affirm Checkout Dialog.

See the HTML test page example which starts the modal checkout flow on button pressing. Checkout Id and Public Api Key have to be provided.

Step 3: Receive Callback and Complete the Transaction

Callback onOpen will be received when the customer has loaded the Affirm checkout flow.

When receiving the OnSuccess callback finish the transaction by sending Complete Affirm Payment message. 

In case of OnFail or onValidationError callback add a refusal_reason to the completion request to inform Verifone about the negative result. 

API Reference: https://verifone.cloud/api-catalog/verifone-ecommerce-api#tag/Payment-Modifications/operation/affirmCompleteTransaction

Request Method: POST

URL: {environment}/api/v2/transactions/affirm_complete

Path parameters: id – string (example: a520d533-e56c-4751-b9da-e448e12a298f)

Headers:

x-vfi-api-idempotencyKey - unique UUID to identify the transaction

Body:

{
"merchant_reference": "7a1db7a8-6f24-4bc5-a51b-cef33fc05140",
	// add refusal reason only in negative case!
"refusal_reason": "ACQUIRER_COMMS_FAILURE"
}

Response

{
"id": "a520d533-e56c-4751-b9da-e448e12a298f",
"authorization_expiration": "auth transaction expiration",
"amount": 150,
"currency_code": "USD",
"created_at": "2019-08-24T14:15:22Z",
"created_by": "ID of creator",
"customer": "ID of a customer",
"merchant_reference": "merchant reference",
"processor": "AFFIRM",
"payment_product": "AFFIRM",
"payment_product_type": "Affirm",
"status": "AUTHORIZED",
"status_reason": "status reason",
"geo_location": 
[
52.370216,
4.895168
],
"country_code": "EU"
}

Explanation of fields:

  • id – the ID of the transaction
  • merchant_reference – the reference specified by the merchant to identify the transaction
  • refusal_reason   the failure reason, only to be set if NOT received the onSuccess callback. Transaction state is set to DECLINED at Verifone side if available in the request.
  • status – the status of the authorization. With a status of AUTHORIZED we know the payment was successfully completed by the customer.

Affirm Checkout Dialog

Note for sandbox testing:

  • Any valid US number format is accepted e.g 2349990000
  • The verification code is set to 123456

After authentication, the customer chooses their payment plan and confirms the bank account to be charged.

Affirm passkey

Affirm payment plan

Affirm selected payment plan

Affirm agreement

Example of HTML page embedding affirm JavaScript library affirm.js

<html>
    <head>
        <title>Affirm Test</title>
        <script type="text/javascript">
            function initialize(public_key){
                _affirm_config = {
                public_api_key: public_key,
                script: "https://cdn1-sandbox.affirm.com/js/v2/affirm.js"
            };
                (function(m,g,n,d,a,e,h,c){var b=m[n]||{},k=document.createElement(e),p=document.getElementsByTagName(e)[0],l=function(a,b,c){return function(){a[b]._.push([c,arguments])}};b[d]=l(b,d,"set");var f=b[d];b[a]={};b[a]._=[];f._=[];b._=[];b[a][h]=l(b,a,h);b[c]=function(){b._.push([h,arguments])};a=0;for(c="set add save post open empty reset on off trigger ready setProduct".split(" ");a<c.length;a++)f[c[a]]=l(b,d,c[a]);a=0;for(c=["get","token","url","items"];a<c.length;a++)f[c[a]]=function(){};k.async=
                !0;k.src=g[e];p.parentNode.insertBefore(k,p);delete g[e];f(g);m[n]=b})(window,_affirm_config,"affirm","checkout","ui","script","ready","jsReady");
            }
            function showDialog(){
                var public_key =  document.getElementById("public_key").value;
                initialize(public_key);
                var checkoutId =  document.getElementById("checkout-id").value;
                var checkoutInfo = {
                    "checkoutAri": checkoutId,
                    "metadata": {
                        "mode":"modal"
                    }
                };

                var callbacks = {
                    onOpen: function(res){
                        alert("Open");
                        console.log(res);
                    },
                    onValidationError: function(res){
                        alert("Validation Error");
                        console.log(res);
                    },
                    onFail: function(res){
                        alert("Failed");
                        console.log(res);
                    },
                    onSuccess: function(res){
                        alert("OnSuccess");
                        console.log(res);
                    }
                }
                affirm.checkout(checkoutInfo);
                affirm.checkout.open(callbacks);
            }
        </script>
    </head>
    <body>        
        <input type="text" id="public_key" value="WEP5F08QZR50F2RQ">
        <input type="text" id="checkout-id" value="UNM4DMNALG3QER7B">
        <input type="button" value="Pay" onclick="showDialog()">
    </body>
</html>

Additional steps

Capture an authorized Affirm payment 

Use the transaction id to capture an Affirm Sale transaction: https://verifone.cloud/docs/online-payments/payment-actions/capturing-authorisation.

Refund an Affirm payment

Use the transaction id to refund an Affirm Sale transaction: https://verifone.cloud/docs/online-payments/payment-actions/refunds.

Perform a Void on an Affirm payment

Use the transaction id to void an Affirm Sale transaction: https://verifone.cloud/docs/online-payments/payment-actions/void.

Need help?

Do you have a question? If you didn’t find the answer you are looking for in our documentation, you can contact our Support teams for more information. If you have a technical issue or question, please contact us. We are happy to help.

Not yet a Verifone customer?

We’ll help you choose the right payment solution for your business, wherever you want to sell, in-person or online. Our team of experts will happily discuss your needs.

Verifone logo