When your customers go through the Affirm checkout flow, you can see their status in real-time via the Affirm API. We send a webhook request to your server when a customer:
Receives a credit decision
Confirms their loan
You can use this information for customer service purposes, such as phone support, or to identify potential customers for email marketing campaigns. You can also use Status Visibility for in-checkout session (push) notifications and feedback. This guide covers how to receive Status Visibility updates from Affirm.
## Checkout events
|User experience||Affirm event||Webhook event|
|Selects Affirm as payment option and is sent to Affirm||Checkout created||opened|
|Creates or signs into an Affirm account||none||none|
|Processing Screen||Approval decision||_ approved _ not_approved \* more_information_needed|
|Selects loan terms and agrees to disclosures||none||none|
|Clicks confirm and is sent back to merchant site||Checkout confirmation||confirmed|
## Event definitions
Customers must opt-in for the approval decisions to be included. The `
confirmed` event is the only webhook event that is guaranteed to be present for each successful Affirm checkout attempt. All other events (approved/not approved/etc.) will only be present if the customer has opted into the Affirm data sharing policy. Customers are actively prompted to enable data sharing, and they can toggle this setting ("Personalized Services") in their Affirm user profile at any time (<https://www.affirm.com/u/#/settings>).
When the customer has opened the checkout link and sees the account sign-in/sign-up screen. This is the first step of the Affirm checkout flow.
The customer has been approved for their Affirm purchase.
The customer has been declined credit for some reason. The reason is purposely ambiguous and may be due to credit-worthiness, inability to verify identity, or insufficient financial records.
**More Information Needed**
The customer was required to provide additional information to determine credit-worthiness or identity and exited the checkout without providing the requested information.
The customer has confirmed the loan. This is the last step of the Affirm checkout flow, which should subsequently trigger charge authorization.
In order to receive Status Visibility updates from Affirm:
Affirm will send an HTTP `
POST` request to a URL that you provide to your Client Success Manager at Affirm. That URL should be a page or endpoint that you've set up to receive requests from our servers.
Receives POST method
Returns 2xx status
Support TLS 1.2 (self-signed or expired certificates are not accepted)
Rate dependent on merchant checkout traffic
Inbound IP is dynamic
**Webhook Request Properties:**
Origin IP is dynamic
Number of fields varies; is based on:
Event type - approved/declined/more_information events have conditional fields
User opt-in - dictates whether conditional fields are present
**Respond to a webhook event:**
Your endpoint should respond to Affirm with a 2xx status code to communicate that you successfully received the webhook event notification. Affirm will treat all other response types as a failed delivery, including 3xx status codes. This means that we will treat URL redirections and "Not Modified" responses as failures. Affirm will ignore any other information returned in the request headers or request body.
Affirm doesn't currently resend a webhook event if your endpoint didn't successfully receive it.
We can support Basic Authentication in the URL. You'll need to provide your endpoint URL username and password to your Client Success Manager.
Affirm signs webhook requests so you can optionally verify that Affirm is sending the request instead of a third-party pretending to be Affirm. Each request includes a base-64 encoded header, X-Affirm-Signature. The value of the header is an HMAC-SHA256 hash signature computed from the request payload and [your private API key found in your merchant dashboard](🔗).
**Replay attack prevention**
If a third-party intercepts a request payload and its signature, your endpoint is susceptible to a replay attack. To mitigate these attacks, we include a timestamp in the X-Affirm-Signature header. Since the timestamp is part of the signed payload, the attacker cannot change the timestamp without invalidating the signature. If the signature is valid but the timestamp is old, you should reject the request. We recommend rejecting a response with a timestamp 5 minutes older than the current time.
## Checkout webhook request body
|Column Title||Column Title||Column Title|
|**checkout_token**||_string_||When the user exits, cancels, or is declined in the Affirm checkout flow|
|**event**||_enum_||_ opened _ approved _ not_approved _ more_information_needed \* confirmed|
|**order_id**||_string_||\*(Optional) Must be enabled by Affirm. Only included if merchant passes the value in the checkout object|
|**webhook_session_id**||_string_||\*(Optional) Must be enabled by Affirm. Only included if merchant passes the value in the checkout object|
order_id` and `
webhook_session_id` fields are unavailable in Shopify.
You can reconcile with your own customer records based on any of these fields:
Checkout_token - provided by Affirm
Order ID - provided by the Merchant
Webhook Session ID - provided by the Merchant
order_id` and `
webhook_session_id` fields are unavailable in Shopify. Please reach out to your Client Success Manager at Affirm. They can provide access to the customer email address to be received in the webhook for reconciliation.
If using an Affirm-provided field, such as the checkout_token, you would need to store this ID in your system to later reconcile against incoming webhook requests.
If using one of your known fields (order_id, customer email, webhook_session_id), you should be able to reconcile the incoming webhook requests with the information you have on-hand.
order_id` and `
webhook_session_id` sent in the checkout object is in all incoming webhook requests for that checkout attempt. You can reconcile this data with your customer records.