# Issuing transactions Learn how to use Issuing to handle transactions. After an [authorisation](https://docs.stripe.com/issuing/purchases/authorizations.md) is approved and is captured, the `status` on the authorisation is set to `closed` and a [Transaction](https://docs.stripe.com/api.md#issuing_transaction_object) object is created. This normally happens within 24 hours; however hotels, airlines, and car rental companies are able to capture up to 31 days after authorisation. When an authorization is captured, two things happen. - The `status` on the authorisation is set to `closed`, releasing the purchase amount held by that authorisation. A [balance transaction](https://docs.stripe.com/reports/balance-transaction-types.md) of type `issuing_authorization_release` is created to represent this. - A new transaction object of type `capture` is created. The purchase amount is deducted from the [balance you’re using for Issuing](https://docs.stripe.com/issuing/funding/balance.md). (See full diagram at https://docs.stripe.com/issuing/purchases/transactions) [Spending controls](https://docs.stripe.com/issuing/controls/spending-controls.md), [real time authorisation controls](https://docs.stripe.com/issuing/controls/real-time-authorizations.md), and card status (whether a card is active or not) don’t apply for capture. They can be used to determine whether authorisations are approved, but captures for approved authorisations always succeed. ## Handling other transactions In addition to regular transactions, there are a few other cases that you should be ready to handle. #### Refunds Refunds are transactions with `type` of `refund`. When we create a transaction representing a refund or credit, we try to link it to the original payment authorisation. Refunds aren’t necessarily tied to the original payment transaction or authorisation, so linking them is an inexact science. As a result, we might link to an unrelated authorisation or be unable to link to an authorisation at all (for example, if the card is credited rather than refunded). In these cases, the `authorization` field of the transaction is set to `null`, and the transaction won’t be linked to the authorisation. We process all refunds and credits the same way, regardless of their linkage to a payment authorisation. > Refunds will still be processed and credited to you even if your card [status](https://docs.stripe.com/api/issuing/cards/object.md#issuing_card_object-status) is `inactive` or `cancelled`. ### Standard refund example ```json { "id": "ipi_1GTG10EEsyYlpYZ9VJn2xV3B", "object": "issuing.transaction","amount": 100, "authorization": "iauth_1GBZQyEEsyYlpYZ9255L8GQC", "balance_transaction": null, "card": "{{CARD_ID}}", "cardholder": null, "created": 1585783834, "currency": "usd", "livemode": false, "merchant_amount": 100, "merchant_currency": "usd", "merchant_data": { "category": "taxicabs_limousines", "city": "San Francisco", "country": "US", "name": "Rocket Rides", "network_id": "1234567890", "postal_code": "94111", "state": "CA", "url": null }, "metadata": {},"type": "refund" } ``` ### Refund reversals In rare cases, a refund might need to be reversed. This typically occurs when duplicate refunds were processed and one needs to be reversed. Refund reversals are represented as transactions with `type` set to `refund` and a negative `amount` field (the `amount` field is positive for standard refunds). For example, if a merchant accidentally processes two refunds of US$17.70 for the same transaction, the system creates a refund reversal transaction with an amount of US$-17.70 (or a similar amount, accounting for foreign exchange differences) to reverse one of the duplicate refunds. ```json { "id": "ipi_1SftmD05sFo7Lo8prb0oyBgc", "object": "issuing.transaction","amount": -1770, "authorization": "iauth_1GBZQyEEsyYlpYZ9255L8GQC", "balance_transaction": null, "card": "{{CARD_ID}}", "cardholder": null, "created": 1585783834, "currency": "usd", "livemode": false, "merchant_amount": -1770, "merchant_currency": "usd", "merchant_data": { "category": "taxicabs_limousines", "city": "San Francisco", "country": "US", "name": "Rocket Rides", "network_id": "1234567890", "postal_code": "94111", "state": "CA", "url": null }, "metadata": {},"type": "refund" } ``` ### Testing refunds To simulate the creation of a refund transaction, you can use the [Transaction Refund API](https://docs.stripe.com/api/issuing/transactions/test_mode_refund.md) in the Issuing test helpers. ```curl curl -X POST https://api.stripe.com/v1/test_helpers/issuing/transactions/{{ISSUINGTRANSACTION_ID}}/refund \ -u "<>:" ``` To create a refund transaction that doesn’t link to an authorisation, use the [Create Unlinked Refund API](https://docs.stripe.com/api/issuing/transactions/test_mode_create_unlinked_refund.md) in the Issuing test helpers. ```curl curl https://api.stripe.com/v1/test_helpers/issuing/transactions/create_unlinked_refund \ -u "<>:" \ -d "card={{ISSUINGCARD_ID}}" \ -d amount=1000 ``` #### Partial capture Merchants can capture an amount that’s less than the authorised amount. As a result, a transaction might display an amount that’s lower than its linked authorisation. In this case, the amount of funds held by Stripe for an authorisation is the difference of the authorisation amount and all linked capture transaction amounts. ### Testing To simulate the capture of an authorisation that’s below the authorised amount, you can use the [Authorisation Capture API](https://docs.stripe.com/api/issuing/authorizations/test_mode_capture.md) in the Issuing test helpers. ```curl curl https://api.stripe.com/v1/test_helpers/issuing/authorizations/{{ISSUINGAUTHORIZATION_ID}}/capture \ -u "<>:" \ -d capture_amount=1000 ``` #### Over capture Businesses in some [merchant categories](https://docs.stripe.com/issuing/categories.md) (including vehicle rentals, bars and restaurants, and ground transportation) won’t know the final transaction amount at the time of authorisation. These businesses can authorise a card for an amount and then capture funds greater than that amount. For example, a restaurant often authorises a charge for the bill amount and then captures an amount that includes the tip. In this case, the authorised amount is a relatively close estimate of the amount to be captured. However, in a case such as ground transportation, the authorised amount is typically a minimal amount, whereas the captured amount reflects the actual transaction by the cardholder. Sometimes the additional amount captured is excessive and could be the result of fraudulent behaviour. It’s up to you (or your cardholder) to recognise when this is the case and [dispute](https://docs.stripe.com/issuing/purchases/disputes.md) illegitimate transactions. Because over capturing is often legitimate, you can’t block these transactions. ### Testing To simulate the capture of an authorisation above the authorised amount, you can use the [Authorisation Capture API](https://docs.stripe.com/api/issuing/authorizations/test_mode_capture.md) in the Issuing test helpers. ```curl curl https://api.stripe.com/v1/test_helpers/issuing/authorizations/{{ISSUINGAUTHORIZATION_ID}}/capture \ -u "<>:" \ -d capture_amount=1000 ``` #### Multi capture Certain [merchant categories](https://docs.stripe.com/issuing/categories.md) (including airlines, cruise lines, or railway merchants) might authorise a transaction, then capture funds multiple times. This situation might occur when you purchase multiple items that ship separately as they become available. This results in the creation of multiple `issuing_authorization.updated` [webhook events](https://docs.stripe.com/api/events/types.md#event_types-issuing_authorization.updated) and multiple [transactions](https://docs.stripe.com/api.md#issuing_transaction_object). ### Testing To simulate the capture of an authorisation multiple times, you can use the [Authorisation Capture API](https://docs.stripe.com/api/issuing/authorizations/test_mode_capture.md) in the Issuing test helpers. ```curl curl https://api.stripe.com/v1/test_helpers/issuing/authorizations/{{ISSUINGAUTHORIZATION_ID}}/capture \ -u "<>:" \ -d capture_amount=1000 \ -d close_authorization=false ``` You can repeatedly capture the authorisation while setting `close_authorization = false`. To close the authorisation, either set the value to `true` or omit the parameter. #### Force capture Merchants might initiate a capture despite receiving a declined authorization, or even without an authorization. In either case, Stripe creates transaction objects, and we deduct the captured amount from your Issuing balance and send it to the merchant. If we didn’t receive an authorization request for the capture, the transaction objects won’t have a linked authorization object. Sometimes these transactions correspond to legitimate purchases. In other cases, these transactions are unauthorised purchases or a result of fraudulent behaviour. It’s up to you (or your cardholder) to recognise when this is the case and [dispute](https://docs.stripe.com/issuing/purchases/disputes.md) illegitimate transactions. Because some of these transactions are legitimate, you can’t block them. An example of a legitimate transaction without an authorisation is a payment on an airplane. The terminals used on airplanes are usually not connected to the internet. Purchases on flights aren’t able to create authorisations and instead create transactions that are sent after the plane lands. ```json { "id": "ipi_1GTG10EEsyYlpYZ9VJn2xV3B", "object": "issuing.transaction", "amount": -100,"authorization": null, "balance_transaction": null, "card": "{{CARD_ID}}", "cardholder": null, "created": 1585783834, "currency": "usd", "livemode": false, "merchant_amount": -100, "merchant_currency": "usd", "merchant_data": { "category": "airlines_air_carriers", "city": "San Francisco", "country": "US", "name": "Rocket Rides", "network_id": "1234567890", "postal_code": "94111", "state": "CA", "url": null }, "metadata": {}, "type": "capture" } ``` ### Testing To simulate the creation of a force capture, you can use the [Transaction Create Force Capture API](https://docs.stripe.com/api/issuing/transactions/test_mode_create_force_capture.md) in the Issuing test helpers. ```curl curl https://api.stripe.com/v1/test_helpers/issuing/transactions/create_force_capture \ -u "<>:" \ -d "card={{ISSUINGCARD_ID}}" \ -d amount=100 ```