Issuing authorizations
Learn how to use Issuing to handle authorization requests.
When a card is used to make a purchase, it generates an authorisation request, which is approved or declined based on the following steps:
- Stripe checks that the balance used for Issuing has sufficient funds, that the card is active, and that your spending controls allow the authorisation. Sometimes, Stripe immediately approves or declines the authorisation request at this stage.
- Stripe sends an
issuing_authorization.requestevent. If you don’t have a real-time authorisation webhook, we approve the authorisation without sending theissuing_authorization.request. Listen for Stripe events Set up a real-time authorisation webhook to listen for this event so you can synchronously approve/decline Authorisations. - You can approve or decline the authorisation by responding directly to the webhook event. If you don’t approve or decline the
issuing_authorization.requestwithin 2 seconds, Stripe uses your webhook timeout settings to approve or decline the authorisation. - Stripe sends an
issuing_authorization.createdevent, notifying you of the Authorisation creation and decision.
Scenarios without a real-time authorisation request
Sometimes, Stripe receives an authorisation request from the card network and approves or declines it without sending you an issuing_authorization.request event:
- If Stripe decides that the authorisation request can’t be approved (for example, because the card is inactive or your spending controls don’t allow it), we’ll decline it.
- If you don’t have a real-time authorisation webhook configured, and we don’t have a reason to decline the authorisation request, we’ll approve it.
When this occurs, Stripe still sends an issuing_authorization.created event, notifying you of the Authorisation creation. Contact support to enable this event for card verifications.
Refunds
Many businesses send real-time authorisation requests for refunds. Stripe has default logic in place to process these requests. If the business proceeds with sending the refund, you’ll see a refund transaction object.
Authorization updates
When Stripe receives an authorisation request, we send an issuing_authorization.created webhook event. If you approve the authorisation, we deduct the amount from your Issuing balance and hold it in reserve until the authorisation is either captured, voided, or expired without capture. If you decline the authorisation, the status is set to closed and we don’t place any holds.
When the authorisation is captured, a transaction is created and the status of the authorisation is set to closed.
If the authorisation request is voided, we send an issuing_authorization.updated webhook event with its status set to reversed and the amount as 0. We add the voided amount back to your Issuing balance, essentially undoing the balance impact of the original authorisation.
Stripe can expire an authorisation by releasing the hold on the balance of an authorisation after a period of time. If the authorisation request expires without capture, we send an issuing_authorization.updated webhook event with its status set to expired in API versions 2025-03-31.basil or later, or status set to reversed in API versions 2025-03-31.basil or earlier. The amount field represents any remaining amount authorised for possible late captures. We add the expired amount back to your Issuing balance, essentially undoing the balance impact of the original authorisation.
This table describes the sequence of operations on an authorisation and the status associated with each operation:
| Operations on the authorisation object | Status (on versions 2025-03-31.basil and newer) |
|---|---|
| Waiting for response to the real-time authorisation request | Pending |
| The authorisation is declined on the response associated with the real-time authorisation request | Closed |
| The authorisation is approved, but pending capture | Pending |
| The authorisation is approved and then fully captured | Closed |
| The authorisation is approved and then partially captured | Pending |
| The authorisation is approved and then fully reversed | Reversed |
| The authorisation is approved and then partially reversed | Pending |
| The authorisation is approved and then expired by Stripe | Expired |
| The authorisation is approved, partially captured, and then the balance is fully reversed | Closed |
| The authorisation is approved, partially captured, and then expired by Stripe | Closed |
| The authorisation is approved, partially reversed, and then the balance is fully captured | Closed |
| The authorisation is approved, partially reversed, and then expired by Stripe | Expired |
| The authorisation is approved, expired by Stripe, and then fully captured | Expired |
| The authorisation is approved, expired by Stripe, and then partially captured | Expired |
| The authorisation is approved, expired by Stripe, and then fully reversed | Reversed |
| The authorisation is approved, expired by Stripe, and then partially reversed | Expired |
Purchases in different currencies
Cards can be used for purchases in any currency that the card network supports. Stripe automatically converts the currency of the purchase into the card’s currency when holding funds, using the card network’s daily rate.
The merchant_amount represents the cost of the purchase in the local currency. The amount field represents the expected amount of the Transaction in the card’s currency and isn’t final until the Authorisation has been captured.
Handling other authorizations
In addition to regular authorizations, there are a few other cases that you should be ready to handle.
Some authorisations are partially authorised to limit spending. This allows you to authorise a specific lower amount and is useful when there aren’t sufficient funds to cover the full purchase.
Fueling stations in the US are a special example of this. Learn more about fuel dispenser authorisations.
When an authorisation is partially authorised, the is_amount_controllable field on the authorisation request is set to true. You can specify the amount you want to approve by setting the amount in the webhook response body or the approve call.
If you partially approve a cashback authorisation, you must approve the full cashback amount. You can’t set the approved amount lower than the cashback_amount.
Testing
To simulate the creation of a new partial authorisation, you can use the Authorisation Create API in the Issuing test helpers.
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
Fuel dispenser authorisations
When a cardholder attempts a purchase at a fuel dispenser ( MCC 5542), an issuing_authorization.request for 1 USD is sent (called a “status check”). The default amount held is 100 USD to cover the unknown purchase amount. When the cardholder finishes pumping fuel, an issuing_authorization.updated event is sent to reflect the amount of the purchase.
When the fuel dispenser allows a partial authorisation by setting is_amount_controllable to true, you can respond with a lower approved amount, such as US$50, or a higher approved amount. If you respond with a higher amount, you might lose some dispute rights. If a fuel dispenser doesn’t allow partial authorisations, you must either approve the network default amount, and Stripe ignores any amount that you specify, or decline the entire authorisation.
For Commercial Fleet programmes, Stripe receives some information in the Issuing Authorisation fleet and fuel hashes after the fuel has been dispensed. As a result, some of these fields won’t be populated during the issuing_authorization.request webhook and will be sent later in the issuing_authorization.updated webhook.
Recurring authorisations
Stripe permits recurring authorisations on expired cards. Cancel the card or deactivate the cardholder to decline all future recurring authorisations. Captures on previously approved authorisations always succeed.
Using with Treasury for platforms
Authorisations on cards that use funds stored in FinancialAccounts have a treasury field with references to related resources: Transaction, ReceivedCredit and ReceivedDebit.
Authorisation outcomes
When you or Stripe approve or decline an authorisation, this field provides additional detail about the reason for the outcome. To find this, click the authorisation in the Stripe Dashboard or look at the value in request_history.reason.
| Authorisation outcome | Description | Next steps |
|---|---|---|
account_disabled | The authorisation request was declined because your account is disabled. | If the account was disabled due to inactivity, re-enable Issuing on the connected account. For other questions, contact . This replaces the deprecated account_inactive and account_compliance_disabled enums. |
card_active | The authorisation was approved according to your default Issuing settings. Authorisation outcome wasn’t caused by a real-time authorisation webhook or spending controls because neither were configured. | No action required. Authorisation approved. |
card_canceled | The authorisation request was declined because the card was cancelled. | You can’t undo this action. You need to issue a new card. Although the card is no longer active for new purchases, it can still receive refunds in several scenarios, because these are handled by the card issuer and often routed to your bank account or a replacement card. |
card_expired | The authorisation request was declined because the card expired. | Learn more about replacing expired cards. |
card_inactive | The authorisation request was declined because the card was inactive. | Learn how to activate the card. |
cardholder_blocked | The authorisation request was declined because the cardholder is blocked. | This status is non-reversible. You need to create a new cardholder. |
cardholder_inactive | The authorisation request was declined because the cardholder was inactive. | You can activate the cardholder in the Dashboard or using the API update endpoint. Learn more about cardholder status. |
cardholder_verification_required | The authorisation wasn’t approved because the cardholder still required verification. | Learn more by querying the API and obtaining the requirements field of the Cardholder object, or by going to the Cardholder in the Dashboard and checking for any pending requirements. |
insecure_authorization_method | The authorisation request was declined because an insecure authorisation method was used. | You can retry the authorisation by inserting the chip into the terminal or entering the PIN at the point of sale. |
insufficient_funds | The authorisation request was declined because your account had insufficient funds. | Learn about topping up your Issuing balance. If you’re in the Consumer Issuing private preview, refer to this guide instead. |
network_fallback | Stripe timed out or encountered an error when responding to the card network. | If you have a dedicated BIN and configured Stripe Autopilot, the card network approved or declined based on your the related setting configuration. If the card network approved an authorisation that Stripe declined, treat the authorisation as approved. Stripe doesn’t hold the funds, but they might still be captured. |
not_allowed | The charge isn’t allowed on the Stripe network, possibly because it is an ATM withdrawal or cash advance. | Confirm that if you’re a Commercial Issuing user, these aren’t Consumer transactions. |
pin_blocked | The authorisation request was declined because the card’s PIN is blocked. | Learn about managing PINs. For US cards, Stripe configures them to prefer signature verification. If a terminal requests a PIN, that behaviour is determined by the terminal’s settings. Try again on a new Terminal device. |
spending_controls | The authorisation was declined because of your spending controls. | Learn about updating your spending controls. Verify spending controls before processing a transaction when the existing controls match the transaction’s amount or category. The total spent at any given time includes both captures and authorisations. |
suspected_fraud | The authorisation was suspected to be fraud based on Stripe’s risk controls. | Consider implementing Fraud Challenges to avoid this. |
verification_failed | The authorisation failed required verification checks. | See authorization.verification_data for more information in your Dashboard. Possible values include Incorrect PIN, missing expiry date, mismatched expiry, invalid account number, or missing Strong Customer Authentication (when SCA is implemented on the cards). This replaces the deprecated authentication_failed, incorrect_cvc, and incorrect_expiry enums. |
webhook_approved | The authorisation was approved by the real-time authorisation webhook. | No action required. Authorisation approved. Learn more about real-time authorisations. |
webhook_declined | The authorisation was declined by the real-time authorisation webhook. | Learn more about real-time authorisations. Some reasons include insufficient funds and exceeding approval amount limits. |
webhook_error | The response sent through the real-time authorisation webhook is invalid. | Learn more about real-time authorisations. |
webhook_timeout | The real-time authorisation webhook timed out before Stripe received your authorisation decision. | Stripe approved or declined the authorisation based on what you configured in your Issuing default or Autopilot settings. Confirm your settings and try again. |
Scenarios with no record of declined authorisations in the Dashboard or API
In some cases, an authorisation made with an Issuing Card might be declined and neither you or your connected accounts will receive a webhook event or an authorisation record ( iauth_).
In these cases, make sure that you collect as much information as possible about the declined authorisation before contacting Stripe support for assistance.
We recommend including the following information:
- The time of the decline
- The cardholder ( ich _ ) who made the purchase
- The card ( ic _ ) used for the authorisation
- The merchant involved in the authorisation
- Any other circumstances about the authorisation
It’s possible that the authorisation is declined before any related information is transmitted to Stripe. In these cases, the cardholder involved must directly contact the business to determine the cause of the decline because Stripe hasn’t received a record of the authorisation request.
You might encounter additional instances of declines without an associated webhook event or authorisation object that Stripe can assist with. To determine the classification of the decline, contact Stripe support with the information provided above. We can help to determine the most appropriate steps to investigate the declines.