Skip to content
Create account or Sign in
The Stripe Docs logo
/
Ask AI
Create accountSign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer resources
APIs & SDKsHelp
Overview
Use for your business
Treasury
Instant currency conversion
Global Payouts
Issuing for your business
Capital
Embed in your platform
Treasury for platforms
Prebuilt embedded finance
Treasury for platforms v2
Issuing
    Overview
    How Issuing works
    Global availability
    Product and marketing compliance guidance (US)
    Marketing guidance (Europe/UK)
    Manage fraud
    Get started with Issuing
    Onboarding overview
    Choose a cardholder type
    Choose your card type
    Virtual cards
    Physical cards
    Fund your Issuing balance
    Testing
    Integrate Issuing
    Integration guides
    Sample app
    Manage cards
    Digital wallets
    Replacement cards
    Card programs
    Program management
    Processor-only Issuing
    Customize your card program
    Add funds to your card program
    Credit Consumer Issuing
    Consumer prepaid debit cards
    Stablecoin-backed cards
    Controls
    Spending controls
    Lifecycle controls
    Radar
    3DS
    Alerts for updated phone numbers
    Fraud challenges
    Real-time authorizations
    PIN management
    Issuing Elements
    Token management
    Postfunding
    Postfund your integration with Stripe
    Postfund your integration with Dynamic Reserves
    Purchases
    Authorizations
    Transactions
    Disputes
    Merchant categories
    ATM usage
    Enriched merchant data
    Issuing with Connect
    Set up an Issuing and Connect integration
    Update terms of service acceptance
    Connect funding
    Connected accounts, cardholders, and cards
    Inactive connected accounts offboarding
    Embed card management UI
    Issuing with Connect and Accounts V2 APIs
    Set up an Issuing and Connect integration
    Credit
    Overview
    Set up connected accounts
    Manage credit terms
    Report other credit decisions and manage AANs
    Report required regulatory data for credit decisions
    Manage account obligations
    Test credit integration
    Additional information
    Customer support for Issuing and Treasury for platforms
    Issuing watchlist
Capital for platforms
United States
English (United States)
  1. Home/
  2. Money management/
  3. Issuing

Issuing authorizations

Learn how to use Issuing to handle authorization requests.

When a card is used to make a purchase, it generates an authorization request, which is approved or declined based on the following steps:

  1. Stripe checks that the balance used for Issuing has sufficient funds, that the card is active, and that your spending controls allow the authorization. Sometimes, Stripe immediately approves or declines the authorization request at this stage.

  2. Stripe sends an issuing_authorization.request event. If you don’t have a real-time authorization webhook, we approve the authorization without sending the issuing_authorization.request.

    Listen for Stripe events

    Set up a real-time authorization webhook to listen for this event so you can synchronously approve/decline Authorizations.

  3. You can approve or decline the authorization by responding directly to the webhook event. If you don’t approve or decline the issuing_authorization.request within 2 seconds, Stripe uses your webhook timeout settings to approve or decline the authorization.

  4. Stripe sends an issuing_authorization.created event, notifying you of the Authorization creation and decision.

Scenarios without a real-time authorization request

Sometimes, Stripe receives an authorization request from the card network and approves or declines it without sending you an issuing_authorization.request event:

  • If Stripe decides that the authorization 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 authorization webhook configured, and we don’t have a reason to decline the authorization request, we’ll approve it.

When this occurs, Stripe still sends an issuing_authorization.created event, notifying you of the Authorization’s creation.

Refunds

Many businesses send real-time authorization 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 authorization request, we send an issuing_authorization.created webhook event. If you approve the authorization, we deduct the amount from your Issuing balance and hold it in reserve until the authorization is either captured, voided, or expired without capture. If you decline the authorization, the status is set to closed and we don’t place any holds.

When the authorization is captured, a transaction is created and the status of the authorization is set to closed.

If the authorization 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 authorization.

Stripe can expire an authorization by releasing the hold on the balance of an authorization after a period of time. If the authorization 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 authorized for possible late captures. We add the expired amount back to your Issuing balance, essentially undoing the balance impact of the original authorization.

This table describes the sequence of operations on an authorization and the status associated with each operation:

Operations on the authorization objectStatus (on versions 2025-03-31.basil and newer)
Waiting for response to the real-time authorization requestPending
The authorization is declined on the response associated with the real-time authorization requestClosed
The authorization is approved, but pending capturePending
The authorization is approved and then fully capturedClosed
The authorization is approved and then partially capturedPending
The authorization is approved and then fully reversedReversed
The authorization is approved and then partially reversedPending
The authorization is approved and then expired by StripeExpired
The authorization is approved, partially captured, and then the balance is fully reversedClosed
The authorization is approved, partially captured, and then expired by StripeClosed
The authorization is approved, partially reversed, and then the balance is fully capturedClosed
The authorization is approved, partially reversed, and then expired by StripeExpired
The authorization is approved, expired by Stripe, and then fully capturedExpired
The authorization is approved, expired by Stripe, and then partially capturedExpired
The authorization is approved, expired by Stripe, and then fully reversedReversed
The authorization is approved, expired by Stripe, and then partially reversedExpired

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 Authorization 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 authorizations are partially authorized to limit spending. This allows you to authorize 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 authorizations.

When an authorization is partially authorized, the is_amount_controllable field on the authorization 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 authorization, 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 authorization, you can use the Authorization Create API in the Issuing test helpers.

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/test_helpers/issuing/authorizations \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d "card=
{{CARD_ID}}
" \ -d amount=100 \ -d "merchant_data[category]=automated_fuel_dispensers" \ -d is_amount_controllable=true

Fuel dispenser authorizations

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 authorization by setting is_amount_controllable to true, you can respond with a lower approved amount, such as 50 USD, 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 authorizations, you must either approve the network default amount, and Stripe ignores any amount that you specify, or decline the entire authorization.

For Commercial Fleet programs, Stripe receives some information in the Issuing Authorization 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 authorizations

Stripe permits recurring authorizations on expired cards. Cancel the card or deactivate the cardholder to decline all future recurring authorizations. Captures on previously approved authorizations always succeed.

Using with Treasury for platforms

Authorizations on cards that use funds stored in FinancialAccounts have a treasury field with references to related resources: Transaction, ReceivedCredit, and ReceivedDebit.

Authorization outcomes

When you or Stripe approve or decline an authorization, this field provides additional detail about the reason for the outcome. To find this, click the authorization in the Stripe Dashboard or look at the value in request_history.reason.

Authorization outcomeDescriptionNext steps
account_disabledThe authorization 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 support-issuing@stripe.com. This replaces the deprecated account_inactive and account_compliance_disabled enums.
card_activeThe authorization was approved according to your default Issuing settings. Authorization outcome wasn’t caused by a real-time authorization webhook or spending controls because neither were configured.No action required. Authorization approved.
card_canceledThe authorization request was declined because the card was canceled.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_expiredThe authorization request was declined because the card expired.Learn more about replacing expired cards.
card_inactiveThe authorization request was declined because the card was inactive.Learn how to activate the card.
cardholder_blockedThe authorization request was declined because the cardholder is blocked.This status is non-reversible. You need to create a new cardholder.
cardholder_inactiveThe authorization 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_requiredThe authorization 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 navigating to the Cardholder on the Dashboard and checking for any pending requirements.
insecure_authorization_methodThe authorization request was declined because an insecure authorization method was used.You can retry the authorization by inserting the chip into the terminal or entering the PIN at the point of sale.
insufficient_fundsThe authorization 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_fallbackStripe timed out or encountered an error when responding to the card network.If you have a dedicated BIN and have configured Autopilot, the card network approved or declined the authorization based on your STIP configuration.
not_allowedThe 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_blockedThe authorization 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 behavior is determined by the terminal’s settings. Try again on a new Terminal device.
spending_controlsThe authorization 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 authorizations.
suspected_fraudThe authorization was suspected to be fraud based on Stripe’s risk controls.Consider implementing Fraud Challenges to avoid this.
verification_failedThe authorization 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_approvedThe authorization was approved by the real-time authorization webhook.No action required. Authorization approved. Learn more about real-time authorizations.
webhook_declinedThe authorization was declined by the real-time authorization webhook.Learn more about real-time authorizations. Some reasons include insufficient funds and exceeding approval amount limits.
webhook_errorThe response sent through the real-time authorization webhook is invalid.Learn more about real-time authorizations.
webhook_timeoutThe real-time authorization webhook timed out before Stripe received your authorization decision.Stripe approved or declined the authorization based on what you configured in your Issuing default or Autopilot settings. Confirm your settings and try again.

Scenarios with no record of declined authorizations in the Dashboard or API

In some cases, an authorization made with an Issuing Card might be declined and neither you or your connected accounts will receive a webhook event or an authorization record (iauth_).

In these cases, make sure that you collect as much information as possible about the declined authorization before reaching out to 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 authorization
  • The merchant involved in the authorization
  • Any other circumstances surrounding the authorization

It’s possible that the authorization 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 authorization request.

You might encounter additional instances of declines without an associated webhook event or authorization 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.

Was this page helpful?
YesNo
  • Need help? Contact Support.
  • Chat with Stripe developers on Discord.
  • Check out our changelog.
  • Questions? Contact Sales.
  • LLM? Read llms.txt.
  • Powered by Markdoc
On this page
Advertisement
Advertisement