Getting Started with Sources Preview

    Accept different methods of payment through a single integration. If you need help after reading this, search our documentation or check out answers to common questions. You can even chat live with other developers in #stripe on freenode.

    Sources is a standardized approach to creating payments using any of our supported payment methods. It abstracts away the differences between each method, eliminating the need to develop separate processes for each method of payment you want to support.

    Creating a payment using Sources is a five-step process:

    1. Create a Source object that represents the customer's payment method
    2. Have the customer take any action that might be required
    3. Confirm the source is ready to use
    4. Make a charge request using the source
    5. Confirm the charge request succeeded and the payment is complete

    Step 1: Create a Source object

    A Source object is either created client-side using Stripe.js or server-side using the API. To create a source with Stripe.js, first include the library within your payment page and set your publishable API key.

    Once included, use the following source.create method to create a source, providing any payment method-specific information. For example, to create a source for an iDEAL payment:

    Stripe.source.create({
      type: 'ideal',
      amount: 1099,
      currency: 'eur',
      owner: {
        name: 'Jenny Rosen',
      },
      redirect: {
        return_url: 'https://shop.example.com/crtA6B28E1',
      },
    }, stripeResponseHandler);
    

    Client-side creation of card sources

    Credit and debit card information must be handled in a PCI compliant manner. To ensure that no sensitive card information touches your server, card-based sources must be created client-side. Refer to our cards or 3D Secure documentation to learn more.

    Server-side source creation

    The use of Stripe.js to create a source is optional for most payment methods, but highly recommended. If you forgo this step and pass the information directly to Stripe when creating a Source object, you must take appropriate steps to safeguard any sensitive information that passes through your servers.

    curl https://api.stripe.com/v1/sources \
       -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
       -d amount=1099 \
       -d currency=eur \
       -d type=ideal \
       -d redirect[return_url]="https://shop.example.com/crtA6B28E1"
    
    # 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_BQokikJOvBiI2HlWgH4olfQ2"
    
    source = Stripe::Source.create({
      amount: 1099,
      currency: 'eur',
      type: 'ideal',
      redirect: {
        return_url: 'https://shop.example.com/crtA6B28E1'
      },
    })
    
    # 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_BQokikJOvBiI2HlWgH4olfQ2"
    
    source = stripe.Source.create(
      amount=1099,
      currency='eur',
      type='ideal',
      redirect={
        'return_url': 'https://shop.example.com/crtA6B28E1'
      },
    )
    
    // 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_BQokikJOvBiI2HlWgH4olfQ2");
    
    $source = \Stripe\Source::create(array(
      "amount" => 1099,
      "currency" => "eur",
      "type" => "ideal",
      "redirect" => array(
        "return_url" => "https://shop.example.com/crtA6B28E1"
      ),
    ));
    
    // 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_BQokikJOvBiI2HlWgH4olfQ2";
    
    Map<String, Object> sourceParams = new HashMap<String, Object>();
    sourceParams.put("amount", 1099);
    sourceParams.put("currency", "eur");
    sourceParams.put("type", "ideal");
    Map<String, Object> redirectParams = new HashMap<String, Object>();
    redirectParams.put("return_url", "https://shop.example.com/crtA6B28E1");
    sourceParams.put("redirect", redirectParams);
    Source source = Source.create(sourceParams);
    
    // 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
    var stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    var source = stripe.sources.create({
      amount: 1099,
      currency: "eur",
      type: "ideal",
      redirect: {
        return_url: "https://shop.example.com/crtA6B28E1"
      },
    }, function(err, source) {
      // asynchronously called
    });
    

    Using either method, Stripe returns a Source object containing the relevant details for the specified method of payment.

    {
      "id": "src_16xhynE8WzK49JbAs9M21jaR",
      "object": "source",
      "amount": 1099,
      "client_secret": "src_client_secret_UfwvW2WHpZ0s3QEn9g5x7waU",
      "created": 1445277809,
      "currency": "eur",
      "flow": "redirect",
      "livemode": true,
      "owner": {
        "address": null,
        "email": null,
        "name": "Jenny Rosen",
        "phone": null,
        "verified_address": null,
        "verified_email": null,
        "verified_name": "Jenny Rosen",
        "verified_phone": null
      },
      "redirect": {
        "return_url": "https://shop.example.com/crtA6B28E1",
        "status": "pending",
        "url": "https://pay.stripe.com/redirect/src_16xhynE8WzK49JbAs9M21jaR?client_secret=src_client_secret_UfwvW2WHpZ0s3QEn9g5x7waU"
      },
      "status": "pending",
      "type": "ideal",
      "usage": "single_use",
      "ideal": {
        "bank": "ing"
      }
    }

    Source creation in mobile applications

    If you’re building an iOS or Android app, you can implement sources using our mobile SDKs. Refer to our sources documentation for iOS or Android to learn more.

    Single-use and reusable sources

    Certain payment methods allow for the creation of sources that can be reused for additional payments without your customer needing to complete the payment process again. Sources that can be reused have their usage parameter set to reusable.

    If a source can only be used once, this parameter is set to single_use and a source must be created each time a customer makes a payment. Refer to the specific payment method documentation to find out if a source can be reused.

    Step 2: Have the customer take any action that might be required

    Some payment methods require your customer to complete a certain action before the source can be used in a charge request. For instance, customers using iDEAL must be redirected to their online banking service to authorize the payment.

    The source’s flow parameter denotes what action, if any, your customer needs to take. There are four possible values you can expect:

    Flow Description
    none No action is required from your customer. Some payment methods, such as cards (excluding 3D Secure), require no additional authentication beyond collecting the payment information from customers. Sources for payment methods that require no action are immediately ready to use in a charge request.
    redirect Your customer must be redirected to their online banking service (either a website or mobile banking app) to approve the payment. The Source object contains the URL to redirect your customer to.
    code_verification Your customer must verify ownership of their account by providing a code that you post to the Stripe API for authentication. For instance, customers using ACH must verify ownership of their account by providing micro-deposits amounts.
    receiver Your customer must push funds to the account information provided. The Source object contains the necessary account details that your customer must push funds to. For instance, customers paying with Bitcoin are provided with an address to send bitcoin to.

    Step 3: Confirm that the source is ready to use

    When a source is created, its status is initially set to either pending or chargeable, depending on whether the payment method used requires any further customer action. A pending source must transition to chargeable before it can be used in a charge request. This occurs once the required customer action has been taken (e.g., authorizing the payment with their banking service).

    If the payment method requires no customer action, then the source is created with its status immediately set to chargeable. It can then be immediately used in the creation of a charge request.

    The status of a source can be one of five possible values:

    Status Description
    pending The source has been created and is awaiting customer action
    chargeable The source is ready to use. The customer action has been completed or the payment method requires no customer action.
    consumed a single-use source has already been used
    canceled The source, which was chargeable, has expired because it was not used to make a charge request within a specified amount of time. This is applicable to single-use sources.
    failed Your customer has not taken the required action or revoked your access (e.g., did not authorize the payment with their bank or canceled their mandate acceptance for SEPA direct debits)

    Source webhooks

    To be notified about changes to the source’s Status, you need to make use of webhooks and receive the following events:

    Event Description
    source.chargeable A Source object becomes chargeable after a customer has authenticated and verified a payment
    source.canceled A Source object expired and cannot be used to create a charge
    source.consumed A Source object that was single-use has already been charged
    source.failed A Source object failed to become chargeable as your customer declined to authenticate the payment

    For payment methods where the source is not immediately chargeable, your integration can either wait until it receives the source.chargeable webhook event, make use of client-side polling, or periodically retrieve the source and verify its status.

    Step 4: Make a charge request using the source

    When the source is chargeable, you can make a charge request, using the source ID as the value for the source parameter, to complete the payment.

    curl https://api.stripe.com/v1/charges \
       -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
       -d amount=1099 \
       -d currency=eur \
       -d source=src_18eYalAHEMiOZZp1l9ZTjSU0
    
    # 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_BQokikJOvBiI2HlWgH4olfQ2"
    
    charge = Stripe::Charge.create({
      amount: 1099,
      currency: 'eur',
      source: 'src_18eYalAHEMiOZZp1l9ZTjSU0',
    })
    
    # 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_BQokikJOvBiI2HlWgH4olfQ2"
    
    charge = stripe.Charge.create(
      amount=1099,
      currency='eur',
      source='src_18eYalAHEMiOZZp1l9ZTjSU0',
    )
    
    // 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_BQokikJOvBiI2HlWgH4olfQ2");
    
    $charge = \Stripe\Charge::create(array(
      "amount" => 1099,
      "currency" => "eur",
      "source" => "src_18eYalAHEMiOZZp1l9ZTjSU0",
    ));
    
    // 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_BQokikJOvBiI2HlWgH4olfQ2";
    
    Map<String, Object> chargeParams = new HashMap<String, Object>();
    chargeParams.put("amount", 1099);
    chargeParams.put("currency", "eur");
    chargeParams.put("source", "src_18eYalAHEMiOZZp1l9ZTjSU0");
    
    Charge charge = Charge.create(chargeParams);
    
    // 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
    var stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    stripe.charges.create({
      amount: 1099,
      currency: "eur",
      source: "src_18eYalAHEMiOZZp1l9ZTjSU0",
    }, function(err, charge) {
      // asynchronously called
    });
    
    // 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_BQokikJOvBiI2HlWgH4olfQ2"
    
    chargeParams := &stripe.ChargeParams{
      Amount: 1099,
      Currency: "eur",
    }
    chargeParams.SetSource("src_18eYalAHEMiOZZp1l9ZTjSU0")
    ch, err := charge.New(chargeParams)
    

    Step 5: Confirm that the charge has succeeded and the payment is complete

    Depending on the payment method, the funds from the charge request might be available immediately (e.g., card payments) or might take a few days (e.g., ACH debits). The charge’s status parameter indicates whether or not the charge has been successful and funds are available. The status can be one of three values:

    Status Description
    pending The charge is pending and payment is not yet complete
    succeeded the charge has succeeded and the payment is complete
    failed the charge has failed and the payment has not been completed

    Some payment methods, such as credit and debit cards, receive immediate (synchronous) confirmation about whether the charge was successful, so you can instantly determine if the payment is complete.

    For methods that are not immediate (asynchronous), the status of a charge can remain in a pending state for several days after its creation before it is updated to either succeeded or failed. For these types of payment methods, you should only fulfill your customer’s order once the charge has been successful. This confirms that the payment is complete and the funds are guaranteed as available. If a charge fails, the order has not been paid for.

    Charge webhooks

    To be notified about changes to the charge’s status, you should make use of webhooks and receive the following events:

    • charge.succeeded: the charge has succeeded
    • charge.failed: the charge has failed

    You can make use of the charge.succeeded webhook to confirm when the charge’s status has transitioned to succeeded so you can fulfill your customer’s order.

    Best practices for integrating payment methods

    By taking into consideration the flexibility of Sources when designing your checkout flow, you can minimize any changes required to support additional payment methods. In a typical checkout flow for card payments (excluding 3D Secure), your integration collects the card information and creates a source, then immediately uses it to make a charge request. As there is no additional action for the customer to take, and card payments provide synchronous confirmation, we can immediately confirm if the payment is successful and that the funds are guaranteed—the use of webhooks isn’t necessary.

    Other payment methods may require your customer to take additional action before a source is chargeable (e.g., iDEAL), or it can take a few days for the funds to be received (e.g., ACH). When making use of these types of payment methods, the use of webhooks is often necessary to determine the status of the Source and Charge objects relating to a payment, even when using client-side polling.

    To ensure that your checkout process is as flexible as possible to support different methods of payment, we recommend the following approach.

    • Your integration is set up to receive webhooks from Stripe so it can determine the status of Source and Charge objects, should you make use of payment methods other than cards
    • All necessary payment information is collected from your customer and used to create a source
    • Consider storing any order information (e.g., order number) as metadata when creating a source. This is useful when handling payment methods that require a customer action. Your integration can make a charge request once the source.chargeable webhook has been received, retrieving any metadata from the event in the process.
    • If required, have your customer take the appropriate action while informing them that the payment is being processed. Your integration can determine what action to take, if any, from the Source object’s flow parameter.
    • Once the charge.succeeded webhook is received (either instantly or after a certain amount of time), the funds are confirmed and you can notify the customer that the payment has been completed

    Considerations for Stripe Connect platforms

    Stripe Connect platform owners can make use of additional payment methods supported with Sources. How you approach the use of additional payment methods is dependent on whether your platform uses standalone or managed accounts. To learn more about creating payments for connected users, and which approach is best for you, refer to our Connect payments and fees documentation.

    Creating sources on connected accounts

    Should you need to create sources directly on your platform’s connected accounts, you can do so by passing source.stripeAccount with a value of a connected account’s ID when using Stripe.js.

    // Set the connected Stripe Account on which the source should be created
    Stripe.source.stripeAccount = "acct_24BFMpJ1svR5A89k";
    
    Stripe.source.create({
      type: 'ideal',
      amount: 1099,
      currency: 'eur',
      owner: {
        name: 'Jenny Rosen',
      },
      redirect: {
        return_url: 'https://shop.example.com/crtA6B28E1',
      },
    }, stripeResponseHandler);
    

    If you’re creating sources server-side, you can make use of authentication using the Stripe-Account header with any of our supported libraries.

    Creating charges on standalone accounts

    These are normal Stripe accounts controlled by the account holder, the platform’s user. As such, each account must independently meet the requirements of a payment method (e.g., country or currency restrictions). The account holder must also activate the payment methods they wish to use, accepting any service agreements that might be necessary.

    Charge requests for payment methods supported by Sources for standalone accounts must be created directly on the connected account which has activated the necessary payment method. Payments created directly on a connected account are only be available on that account.

    Creating charges on managed accounts

    Unlike standalone accounts, managed accounts are fully controlled by the platform. It is only the platform that needs to meet the requirements of, and activate, a payment method.

    Charge requests for payment methods supported by Sources for managed accounts must be created through the platform’s account, using the destination parameter. Customers are charged only by your platform, which then transfers the necessary amount to the destination account.

    Next steps