Card payments on the Charges API

    Learn how to charge, save, and authenticate credit and debit cards on Stripe.

    The Charges API is available for getting started quickly—without handling additional authentication—in countries unaffected by Strong Customer Authentication. If you have customers in other countries, plan to expand beyond the U.S. and Canada, or make charges on behalf of a business in another country, use the Payment Intents API.

    Most of the world is increasingly familiar with authenticated payments, as regulations and payment methods evolve. Although Stripe’s original integration lets you tokenize and charge a card simply, it doesn’t prepare you for global growth.

    About the API

    The Charges and Tokens APIs work together for simple payments.

    After securely collecting and tokenizing your customer’s credit card, you can either charge or save the card for later. Unlike tokenization, which occurs in the browser, charge attempts are made from your server, normally using one of our client libraries. If you haven’t already, install the library for your favorite language now.

    These APIs are not designed for Strong Customer Authentication (SCA). As new regulations and regional payment methods come with different requirements, switch to our supported APIs to support them.

    Migrating

    The Charges API is limited. To get the latest Stripe features, migrate to the Payment Intents API now.

    Charges API

    A traditional token-based integration
    • Collect the customer's payment information in the browser with Elements
    • Tokenize the payment information with Stripe.js
    • Perform a request to send the token to your server
    • Use the token to create a charge on your server with the desired amount and currency
    • Fulfill the customer's order if payment is successful

    Payment Intents API

    A new Payment Intents API integration
    • Create a PaymentIntent on your server with the desired amount and currency
    • Send the PaymentIntent's client secret to the client side
    • Collect the customer's payment information in the browser with Elements
    • Use Stripe.js or the mobile SDKs to handle 3D Secure and complete the payment on the client
    • Use webhooks to fulfill the customer's order if the payment is successful

    Using the Charges API

    Although unsupported, the Stripe Charges API isn’t going away. Until you upgrade your integration, you can still use Charges to collect payments and more:

    Haven’t set up our libraries or SDKs yet? Go get started on web, iOS, or Android.

    Dynamic statement descriptor

    By default, your Stripe account’s statement descriptor appears on customer statements whenever you charge their card. Additionally, you can set the statement descriptor dynamically on every charge request with the statement_descriptor argument on the Charge object

    curl https://api.stripe.com/v1/charges \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=999 \ -d currency=usd \ -d description="Example charge" \ -d source=tok_visa \ -d statement_descriptor="Custom descriptor"
    # Set your secret key: remember to change this to your live secret key in production # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' # Token is created using Checkout or Elements! # Get the payment token ID submitted by the form: token = params[:stripeToken] charge = Stripe::Charge.create({ amount: 999, currency: 'usd', description: 'Example charge', source: token, statement_descriptor: 'Custom descriptor', })
    # Set your secret key: remember to change this to your live secret key in production # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' # Token is created using Checkout or Elements! # Get the payment token ID submitted by the form: token = request.form['stripeToken'] # Using Flask charge = stripe.Charge.create( amount=999, currency='usd', description='Example charge', source=token, statement_descriptor='Custom descriptor', )
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); // Token is created using Checkout or Elements! // Get the payment token ID submitted by the form: $token = $_POST['stripeToken']; $charge = \Stripe\Charge::create([ 'amount' => 999, 'currency' => 'usd', 'description' => 'Example charge', 'source' => $token, 'statement_descriptor' => 'Custom descriptor', ]);
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; // Token is created using Checkout or Elements! // Get the payment token ID submitted by the form: String token = request.getParameter("stripeToken"); Map<String, Object> params = new HashMap<>(); params.put("amount", 999); params.put("currency", "usd"); params.put("description", "Example charge"); params.put("source", token); params.put("statement_descriptor", "Custom descriptor"); Charge charge = Charge.create(params);
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); // Token is created using Checkout or Elements! // Get the payment token ID submitted by the form: const token = request.body.stripeToken; // Using Express (async () => { const charge = await stripe.charges.create({ amount: 999, currency: 'usd', description: 'Example charge', source: token, statement_descriptor: 'Custom descriptor', }); })();
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" // Token is created using Checkout or Elements! // Get the payment token ID submitted by the form: token := r.FormValue("stripeToken") params := &stripe.ChargeParams{ Amount: stripe.Int64(999), Currency: stripe.String(string(stripe.CurrencyUSD)), Description: stripe.String("Example charge"), StatementDescriptor: stripe.String("Custom descriptor"), } params.SetSource(token) ch, _ := charge.New(params)
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; // Token is created using Checkout or Elements! // Get the payment token submitted by the form: var token = model.Token; // Using ASP.NET MVC var options = new ChargeCreateOptions { Amount = 999, Currency = "usd", Description = "Example charge", Source = token, StatementDescriptor = "Custom descriptor", }; var service = new ChargeService(); Charge charge = service.Create(options);

    Statement descriptors are limited to 22 characters, cannot use the special characters <, >, ', ", or *, and must not consist solely of numbers.

    When setting the statement descriptor dynamically on credit and debit card charges, the dynamic portion is appended to the settlement merchant’s statement descriptor (separated by an * and an empty space). For example, a statement descriptor for a business, named FreeCookies, that includes the kind of cookie purchased might look like FREECOOKIES* SUGAR.

    The * and empty space count towards the 22 character limit and Stripe automatically allots 10 characters for the dynamic statement descriptor. This means that the settlement merchant’s descriptor might be truncated if it’s longer than 10 characters (assuming the dynamic statement descriptor is also greater than 10 characters). If the dynamic statement descriptor is also greater than 10 characters, both descriptors are truncated at 10 characters.

    If you’re having issues with the character limits, you can set a shortened descriptor in the Stripe Dashboard to shorten the settlement merchant’s descriptor. This allows more room for the dynamic statement descriptor. The shortened descriptor:

    • Replaces the settlement merchant’s statement descriptor when using dynamic descriptors.
    • Can be between 2 and 10 characters.

    If you’re not sure what the statement descriptors look like when they’re combined, you can check them in the the Stripe Dashboard.

    Storing information in metadata

    Stripe supports adding metadata to the most common requests you make, such as processing charges. Metadata isn’t shown to customers or factored into whether or not a charge is declined or blocked by our fraud prevention system.

    Through metadata, you can associate other information—meaningful to you—with Stripe activity. Any metadata you include is viewable in the Dashboard (e.g., when looking at the page for an individual charge), and is also available in common reports and exports. As an example, your store’s order ID can be attached to the charge used to pay for that order. Doing so allows you, your accountant, or your finance team to easily reconcile charges in Stripe to orders in your system.

    If you are using Radar, consider passing any additional customer information and order information as metadata. By doing so, you can write Radar rules using metadata attributes and have more information about the payment available within the Dashboard which can expedite your review process.

    curl https://api.stripe.com/v1/charges \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=999 \ -d currency=usd \ -d description="Example charge" \ -d source=tok_visa \ -d "metadata[order_id]"=6735
    # Set your secret key: remember to change this to your live secret key in production # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' # Token is created using Checkout or Elements! # Get the payment token ID submitted by the form: token = params[:stripeToken] charge = Stripe::Charge.create({ amount: 999, currency: 'usd', description: 'Example charge', source: token, metadata: {'order_id' => 6735}, })
    # Set your secret key: remember to change this to your live secret key in production # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' # Token is created using Checkout or Elements! # Get the payment token ID submitted by the form: token = request.form['stripeToken'] # Using Flask charge = stripe.Charge.create( amount=999, currency='usd', description='Example charge', source=token, metadata={'order_id': 6735}, )
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); // Token is created using Checkout or Elements! // Get the payment token ID submitted by the form: $token = $_POST['stripeToken']; $charge = \Stripe\Charge::create([ 'amount' => 999, 'currency' => 'usd', 'description' => 'Example charge', 'source' => $token, 'metadata' => ['order_id' => 6735], ]);
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; // Token is created using Checkout or Elements! // Get the payment token ID submitted by the form: String token = request.getParameter("stripeToken"); Map<String, Object> params = new HashMap<>(); params.put("amount", 999); params.put("currency", "usd"); params.put("description", "Example charge"); params.put("source", token); Map<String, String> metadata = new HashMap<>(); metadata.put("order_id", 6735); params.put("metadata", metadata); Charge charge = Charge.create(params);
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); // Token is created using Checkout or Elements! // Get the payment token ID submitted by the form: const token = request.body.stripeToken; // Using Express (async () => { const charge = await stripe.charges.create({ amount: 999, currency: 'usd', description: 'Example charge', source: token, metadata: {order_id: 6735}, }); })();
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" // Token is created using Checkout or Elements! // Get the payment token ID submitted by the form: token := r.FormValue("stripeToken") params := &stripe.ChargeParams{ Amount: stripe.Int64(999), Currency: stripe.String(string(stripe.CurrencyUSD)), Description: stripe.String("Example charge"), } params.SetSource(token) params.AddMetadata("order_id", 6735) ch, _ := charge.New(params)
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; // Token is created using Checkout or Elements! // Get the payment token submitted by the form: var token = model.Token; // Using ASP.NET MVC var options = new ChargeCreateOptions { Amount = 999, Currency = "usd", Description = "Example charge", Source = token, Metadata = new Dictionary<String, String>() {{"OrderId", "6735"}}, }; var service = new ChargeService(); Charge charge = service.Create(options);

    Collect card payments faster, with less code

    The easiest way to move to our Payment Intents API is to use Checkout, a Stripe-hosted payment page that adjusts to web and mobile browsers.

    Was this page helpful?

    Thank you for helping improve Stripe's documentation. If you need help or have any questions, please consider contacting support.

    On this page