Private preview
Accept gift card payments Private preview
Use Terminal to accept third-party closed-loop gift cards.
Private preview
Request access to the Gift card private preview by contacting your Account Executive or by sending an email to with the following information:
- Use case for in-person and/or online gift card acceptance
- Terminal device and integration type
- Gift card provider
- Country/countries where gift cards will be accepted
- Estimated annual gift card transaction volume
Onboard your gift card provider to Stripe and use the Terminal reader to accept and manage third-party closed-loop magnetic stripe gift cards.
Closed-loop gift cards are stored-value instruments that can only be redeemed at a single business or family of businesses. Unlike open-loop gift cards (such as Visa or Amex gift cards), settlement happens off-Stripe, meaning no funds move on Stripe at redemption time.
How it works
Gift card operations on Terminal fall into two categories:
- Redemption : Use the PaymentIntent flow with gift _ card as a payment method type
- Non-payment operations (activate, check balance, reload, cashout): Send a request to the reader, prompt the cardholder to swipe, and receive a gift _ card _ operation with the result
Availability
- Readers with swipe capability : Stripe Reader the related setting/the related setting , the related setting WisePOS E , and Verifone devices
- Gift card provider : SVS (Stored Value Solutions)
- Gift card format : Magnetic stripe
- Availability : US only
Before you begin
- Onboard your gift card provider to Stripe. Contact your Sales team to onboard your gift card provider
- All API requests require a preview API version header. You must include Stripe-Version: 2026-02-25. preview in every request
Limitations
- You can’t attach gift card payment methods to a Customer object or save them as stored payment methods
- Calling the Refunds endpoint on a gift card PaymentIntent returns an error. You need to refund manually by reloading the original gift card or activating a new one
- You can’t list gift card operations. Use the Retrieve a gift card operation endpoint to look up individual operations by ID
Gift card program constraints
Your gift card provider and program define the rules that govern each card, including:
- Load amounts : The minimum and maximum amount you can add in a single activation or reload.
- Maximum balance : The highest balance a card can hold.
- Denominations : Any fixed or incremental amounts the program allows.
- Expiration : Whether cards expire and when. The provider enforces expiration. Stripe doesn’t enforce it on the provider’s behalf, so a card with a past expiration date can remain usable if the provider still honors it.
Stripe doesn’t define the rules for each card. Stripe forwards each operation to the provider, which validates it against these rules, so an operation with an unsupported amount or other invalid input can fail when the provider processes it. To avoid surprises, make sure your integration only sends values that your program supports.
Gift card provider constraints
SVS (Stored Value Solutions)
- Balance checks on inactive cards return a successful operation with a zero balance. All other operations on inactive cards fail with the card _ not _ activated decline code.
- Payments will always authorize for the available balance on the card if the amount of the payment is greater than the remaining balance. Always set payment_method_options.gift_card.request_partial_authorization to if _ available when accepting SVS gift cards.
- SVS returns previous _ balance only for cashout operations.
- In a sandbox , the payment_reference on the PaymentRecord isn’t unique per transaction.
Non-payment operations
For non-payment gift card operations, the flow is:
- Send the operation request to the reader.
- The reader prompts the cardholder to swipe a gift card.
- Poll the reader or listen for the terminal.reader.action_succeeded webhook.
- Retrieve the completed action and expand the gift _ card _ operation to get the result.
Activate a gift card
Activate a new gift card with an initial load amount. You must activate a gift card before the cardholder can use it for any other operations, including balance checks and redemptions.
Command Line
cURL
Note
Omitting balance doesn’t cause an immediate validation error. Balance requirements vary by gift card brand, so validation happens after the cardholder swipes.
The response returns the reader with action.status set to in_progress:
{
"id": "{{READER_ID}}",
"object": "terminal.reader",
"action": {
"failure_code": null,
"failure_message": null,
"status": "in_progress",
"type": "activate_gift_card"
}
}
After the cardholder swipes, retrieve the Reader to inspect the result. Use the expand parameter to include the full gift_card_operation object:
Command Line
cURL
{
"id": "{{READER_ID}}",
"object": "terminal.reader",
"action": {
"status": "succeeded",
"type": "activate_gift_card",
"activate_gift_card": {
"gift_card": "{{GIFT_CARD_ID}}",
"gift_card_operation": {
"id": "{{GIFT_CARD_OPERATION_ID}}",
"object": "gift_card_operation",
"gift_card": "{{GIFT_CARD_ID}}",
"livemode": false,
"type": "activation",
"balance": {
"amount": 5000,
"currency": "usd"
},
"created": 1234567890,
"completed_at": 1234567891,
"status": "succeeded"
}
}
}
}
Check the gift card balance
Check the remaining balance on an active gift card. You can use this API before a transaction to verify available funds, or to display the balance to the cardholder at their request. When you call the check_gift_card_balance endpoint on the Reader, the reader prompts the cardholder to swipe their card.
Command Line
cURL
The response returns the reader with action.status set to in_progress:
{
"id": "{{READER_ID}}",
"object": "terminal.reader",
"action": {
"failure_code": null,
"failure_message": null,
"status": "in_progress",
"type": "check_gift_card_balance"
}
}
After the cardholder swipes, retrieve the Reader to inspect the result. Use the expand parameter to include the full gift_card_operation object:
Command Line
cURL
{
"id": "{{READER_ID}}",
"object": "terminal.reader",
"action": {
"status": "succeeded",
"type": "check_gift_card_balance",
"check_gift_card_balance": {
"gift_card": "{{GIFT_CARD_ID}}",
"gift_card_operation": {
"id": "{{GIFT_CARD_OPERATION_ID}}",
"object": "gift_card_operation",
"gift_card": "{{GIFT_CARD_ID}}",
"livemode": false,
"type": "balance_check",
"balance": {
"amount": 5000,
"currency": "usd"
},
"created": 1234567890,
"completed_at": 1234567891,
"status": "succeeded"
}
}
}
}
Reload a gift card
Add funds to an existing gift card. Use this when a cardholder wants to increase the balance on a previously activated card.
Command Line
cURL
The response returns the reader with action.status set to in_progress:
{
"id": "{{READER_ID}}",
"object": "terminal.reader",
"action": {
"failure_code": null,
"failure_message": null,
"status": "in_progress",
"type": "reload_gift_card"
}
}
After the cardholder swipes, retrieve the Reader to inspect the result. Use the expand parameter to include the full gift_card_operation object:
Command Line
cURL
The completed action returns previous_balance and the updated balance:
{
"id": "{{READER_ID}}",
"object": "terminal.reader",
"action": {
"status": "succeeded",
"type": "reload_gift_card",
"reload_gift_card": {
"gift_card": "{{GIFT_CARD_ID}}",
"gift_card_operation": {
"id": "{{GIFT_CARD_OPERATION_ID}}",
"object": "gift_card_operation",
"gift_card": "{{GIFT_CARD_ID}}",
"type": "reload",
"balance": {
"amount": 5000,
"currency": "usd"
},
"previous_balance": {
"amount": 0,
"currency": "usd"
},
"created": 1234567890,
"completed_at": 1234567891,
"status": "succeeded"
}
}
}
}
Cash out a gift card
Cash out the full remaining balance on a gift card, setting it to zero. Use this when a cardholder wants to redeem the remaining value as cash, typically to comply with local cash-equivalent laws or store policy.
Command Line
cURL
The response returns the reader with action.status set to in_progress:
{
"id": "{{READER_ID}}",
"object": "terminal.reader",
"action": {
"failure_code": null,
"failure_message": null,
"status": "in_progress",
"type": "cashout_gift_card"
}
}
After the cardholder swipes, retrieve the Reader to inspect the result. Use the expand parameter to include the full gift_card_operation object:
Command Line
cURL
The completed action returns previous_balance showing the balance before cashout:
{
"id": "{{READER_ID}}",
"object": "terminal.reader",
"action": {
"status": "succeeded",
"type": "cashout_gift_card",
"cashout_gift_card": {
"gift_card": "{{GIFT_CARD_ID}}",
"gift_card_operation": {
"id": "{{GIFT_CARD_OPERATION_ID}}",
"object": "gift_card_operation",
"gift_card": "{{GIFT_CARD_ID}}",
"type": "cashout",
"balance": {
"amount": 0,
"currency": "usd"
},
"previous_balance": {
"amount": 5000,
"currency": "usd"
},
"created": 1234567890,
"completed_at": 1234567891,
"status": "succeeded"
}
}
}
}
Void an operation
Void an operation to undo a non-payment operation you performed by mistake—for example, if a cashier accidentally loads 500 USD onto a card instead of 50 USD. You can void activate, reload, and cashout operations within 24 hours. Make void requests from your back end using the Stripe API:
Command Line
cURL
The gift card provider can reject a void if other activity on the card depends on the operation you’re voiding—for example, voiding an activation after the card has already been reloaded. If the provider rejects the void, the original operation stands.
Redeem a gift card
To accept a gift card as payment, use a PaymentIntent. The key differences from a card payment are:
- Include gift _ card in the payment _ method _ types array when creating the PaymentIntent
- Specify the gift card brand (for example, svs ) in the process configuration
- The confirmed PaymentIntent returns a PaymentRecord instead of a Charge . The PaymentRecord tracks the transaction details from the gift card provider, including the amount authorized and processor-specific references
Note
Gift card redemption transactions appear as normal payments in the Stripe Dashboard. You can identify them by the gift_card payment method type on the PaymentIntent.
Create a PaymentIntent
To accept a gift card as payment, create a PaymentIntent with gift_card in the payment_method_types array. Include card_present if you want to allow the cardholder to pay with either a gift card or a standard card.
Command Line
cURL
Setting request_partial_authorization to if_available allows the payment to succeed with a partial amount if the gift card balance is insufficient. If you set it to never (the default), the payment fails when funds are insufficient.
Process the payment
Use process_payment_intent to collect the payment method and confirm in a single step. Specify the gift card brand in the process configuration.
Command Line
cURL
The reader prompts the cardholder to swipe their gift card. After the payment is processed, the PaymentIntent transitions to succeeded and includes a PaymentRecord:
{
"id": "{{PAYMENT_INTENT_ID}}",
"object": "payment_intent",
"amount": 2000,
"currency": "usd",
"status": "succeeded",
"payment_method_types": ["card_present", "gift_card"],
"payment_record": {
"id": "{{PAYMENT_RECORD_ID}}",
"object": "payment_record",
"amount": {
"currency": "usd",
"value": 2000
},
"amount_requested": {
"currency": "usd",
"value": 2000
},
"processor_details": {
"type": "svs",
"svs": {
"payment_reference": "svs_transaction_id"
}
}
}
}
Partial authorization
If the gift card balance is insufficient for the full amount, a partial authorization can occur. Handle partial authorizations by collecting the remaining balance through a second payment method.
To enable partial authorization, set payment_method_options[gift_card][request_partial_authorization] to if_available when creating the PaymentIntent. If the gift card has insufficient funds and partial authorization isn’t enabled (or set to never), the payment fails.
In a partial authorization, amount_authorized on the PaymentRecord is less than amount_requested:
{
"id": "{{PAYMENT_INTENT_ID}}",
"object": "payment_intent",
"amount": 2000,
"amount_received": 500,
"currency": "usd",
"status": "succeeded",
"payment_method_types": ["card_present", "gift_card"],
"payment_record": {
"id": "{{PAYMENT_RECORD_ID}}",
"object": "payment_record",
"amount_authorized": {
"currency": "usd",
"value": 500
},
"amount_canceled": {
"currency": "usd",
"value": 1500
},
"amount_requested": {
"currency": "usd",
"value": 2000
},
"processor_details": {
"type": "svs",
"svs": {
"payment_reference": null
}
}
}
}
Connect platforms
For Connect platforms where the connected account has the relationship with the gift card provider, pass on_behalf_of with the connected account ID on all non-payment operations.
Command Line
cURL
For redemption flows, use on_behalf_of on the PaymentIntent as you would with any other payment method.
Because a gift card redemption doesn’t move money on Stripe, move funds separately when your platform needs to settle with the connected account. If you hold the underlying funds on Stripe, create a transfer to the connected account. If the funds are held outside Stripe, the movement happens out of band and your platform manages it. To collect fees for gift card usage from the connected account, use Account Debits.
Test your integration
You can test your integration with a simulated reader instead of physical hardware. After creating a simulated reader, use the present_payment_method test helper to simulate the cardholder swiping a gift card.
Note
You need to use your own test track2 number received from your gift card provider (for example, SVS) to test with the simulated reader. The simulation API makes an actual API request to your gift card provider’s sandbox environment. Contact your gift card provider to obtain test credentials for their sandbox.
Simulate a non-payment operation
To test non-payment gift card operations (activate, check balance, reload, cashout) with the simulated reader, start the operation, then call the present_payment_method test helper to simulate the swipe.
Start the gift card operation on the simulated reader. This example uses activation, but the same approach works for check_gift_card_balance, reload_gift_card, and cashout_gift_card:
Command Line
cURL
Next, call present_payment_method with type=gift_card to simulate the swipe. Pass the test track2 data from your gift card provider and the gift card brand:
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
After the simulated swipe, retrieve the reader to inspect the result. Use the expand parameter to include the full gift_card_operation object. For example, after the activation operation:
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
Simulate a gift card redemption
To test the redemption (payment) flow with the simulated reader, create a PaymentIntent, process it on the reader, then simulate the swipe.
Create a PaymentIntent with gift_card in the payment_method_types:
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
Process the PaymentIntent on the simulated reader with the gift card brand:
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
Simulate the gift card swipe using present_payment_method:
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
After the simulated swipe, poll the reader or listen for the terminal.reader.action_succeeded webhook to verify the operation completed.
Handle errors
Webhooks
Subscribe to these webhook events to track operation results:
- terminal.reader.action_succeeded : A gift card operation completed. The reader object in the payload contains the result
- terminal.reader.action_failed : A gift card operation failed. Check action. failure _ code and action. failure _ message for details
Caution
The gift_card and gift_card_operation fields only appear in the terminal.reader payload when you register your webhook endpoint with the preview version header Stripe-Version: 2026-02-25.preview.
Timeout errors
If the reader can’t reach Stripe, it displays a failure screen and sends a terminal.reader.action_failed webhook with a failure_code of connection_error. For more details on handling timeouts, see Payment timeout.
Maximum balance constraints
Gift card providers enforce maximum balance limits on activation and reload. Stripe doesn’t impose its own balance cap. If an activation or reload amount exceeds the provider’s maximum, the operation fails with a failure_code of invalid_amount. Contact your gift card provider to confirm their balance limits.
Network decline codes
When a PaymentIntent for a gift card redemption fails, the error response might include a network_decline_code containing the raw decline reason from the gift card provider. This code is provider-specific and not normalized by Stripe. Check with your gift card provider for the meaning of specific network decline codes.
For non-payment operations (activate, reload, check balance, cashout), the reader action uses failure_code with a Stripe-normalized reason instead of a provider-specific network decline code.
