WeChat Pay Payments with Sources Beta

    Use Sources to accept payments using WeChat Pay, a popular payment method in China.

    Stripe users can use Sources—a single integration path for creating payments using any supported method—to accept WeChat Pay payments from customers in China.

    During the payment process, a Source object is created and you receive a WeChat Pay URL that is used, either by QR code or mobile redirect, to authorize the payment in the WeChat app. After completing this, your integration uses the source to make a charge request and complete the payment.

    WeChat Pay is a push-based, single-use and synchronous method of payment. This means that once your customer takes action to authorize the charge there is immediate confirmation about the success or failure of a payment.

    Step 1: Create a Source object

    A Source object is either created client-side using Stripe.js or server-side using the Source creation endpoint, with the following parameters:

    Parameter Value
    type wechat
    amount A positive integer in the smallest currency unit representing the amount to charge the customer (e.g., 1099 for a $10.99 payment).
    currency The currency of the payment. Must be the default currency for your country. Can be aud, cad, eur, gbp, hkd, jpy, sgd, or usd.
    statement_descriptor (optional) A custom statement descriptor for the payment.

    To create a source with Stripe.js, first include the library within your website and set your publishable API key. Once included, use the following createSource method to create a source client-side:

    stripe.createSource({
      type: 'wechat',
      amount: 1099,
      currency: 'usd',
    }).then(function(result) {
      // handle result.error or result.source
    });
    

    Using either method, Stripe returns a Source object containing the relevant details for the method of payment used. Information specific to WeChat is provided within the wechat subhash.

    {
      "id": "src_18eYalAHEMiOZZp1l9ZTjSU0",
      "object": "source",
      "amount": 1099,
      "client_secret": "src_client_secret_UfwvW2WHpZ0s3QEn9g5x7waU",
      "created": 1445277809,
      "currency": "usd",
      "flow": "none",
      "livemode": true,
      "metadata": {},
    See all 27 lines "owner": { "address": null, "email": null, "name": "null", "phone": null, "verified_address": null, "verified_email": null, "verified_name": null, "verified_phone": null }, "status": "pending", "type": "wechat", "usage": "single_use", "wechat": { "qr_code_url": "weixin://wxpay/bizpayurl?pr=RaXzhu4", } }

    Optional: Providing a custom statement descriptor

    WeChat Pay can accept a statement descriptor before the customer is redirected to authorize the payment. By default, your Stripe account’s statement descriptor is used (you can review this in the Dashboard). You can provide a custom descriptor by specifying statement_descriptor when creating a source. WeChat statement descriptors support a maximum of 32 characters.

    stripe.createSource({
      type: 'wechat',
      amount: 1099,
      currency: 'usd',
      statement_descriptor: 'ORDER AT11990',
      owner: {
        name: 'Jenny Rosen',
      },
    }).then(function(result) {
      // handle result.error or result.source
    });
    

    Providing a custom statement descriptor within a subsequent charge request has no effect.

    Error codes

    Source creation for WeChat Pay payments may return any of the following errors:

    Error Description
    payment_method_not_available The payment method is currently not available. You should invite your customer to fallback to another payment method to proceed.
    processing_error An unexpected error occurred preventing us from creating the source. The source creation should be retried.

    Step 2: Have the customer authorize the payment

    When creating a source, its status is initially set to pending and cannot yet be used to make a charge request. Your customer must authorize a WeChat Pay payment to make the source chargeable. Allowing your customer to authorize the payment will need a different flow depending on if the source is being created on the desktop or a mobile application.

    If this is a desktop checkout, you will need to show the customer a QR code created from URL provided within the wechat[qr_code_url]. Alternatively, if on mobile, you need to redirect the customer using the above URL. The customer will then be able use their app to authorize the payment.

    After the authorization process, if the customer has authorized the payment, the Source object’s status will transition to chargeable; it is then ready to be used in a charge request. If your customer declines the payment, the status will transition to failed.

    Testing

    For sources created in test mode, the wechat[qr_code_url] can be scanned using any QR Code scanning application rather than WeChat. The URL leads to a Stripe page that displays information about the API request, and where you can either authorize or cancel the payment.

    Step 3: Charge the Source

    Once the customer has authorized the payment, the source’s status transitions to chargeable and it can be used to make a charge request. This transition happens asynchronously.

    Some customers using WeChat Pay will assume that the order process is complete once they have authorized the payment and received confirmation on WeChat Pay’s app. It is essential that your integration rely on webhooks to determine when the source becomes chargeable in order to create a charge. Please refer to our best practices for more details on how to best integrate payment methods using webhooks.

    Webhooks

    The following webhook events are sent to notify you about changes to the source’s status:

    Event Description
    source.chargeable A Source object becomes chargeable after a customer has authorized and verified a payment.
    source.failed A Source object failed to become chargeable as your customer declined to authorize the payment.
    source.canceled A Source object expired and cannot be used to create a charge.

    Make a charge request using the source

    Once the source is chargeable, from your source.chargeable webhook handler, 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=usd \
       -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: 'usd',
      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='usd',
      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" => "usd",
      "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", "usd");
    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: "usd",
      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: stripe.Int64(1099),
      Currency: stripe.String(string(stripe.CurrencyUSD)),
    }
    chargeParams.SetSource("src_18eYalAHEMiOZZp1l9ZTjSU0")
    ch, err := charge.New(chargeParams)
    

    WeChat Pay Sources are single-use and cannot be used for recurring or additional payments. Refer to our Sources & Customers guide for more information on how single-use Sources interact with Customers.

    Step 4: Confirm that the charge has succeeded

    Since WeChat Pay is a synchronous payment method and the customer has already authorized the payment using the WeChat application, unless there is an unexpected error, the Charge will immediately succeed.

    You will also receive the following webhook event as the charge is created:

    Event Description
    charge.succeeded The charge succeeded and the payment is complete.

    We recommend that you rely on the charge.succeeded webhook event to notify your customer that the payment process has been completed and their order is confirmed. Please refer to our best practices for more details on how to best integrate payment methods using webhooks.

    Disputed payments

    If a customer’s WeChat Pay account is used illicitly, WeChat Pay and Stripe handle the issue internally. In the context of WeChat Pay, payments are only disputed if the customer has a complaint about the provided goods or service. Should a dispute occur, a dispute.created webhook event is sent, and Stripe deducts the amount of the dispute from your Stripe balance.

    Sources expiration

    A chargeable WeChat Pay source must be charged within six hours of becoming chargeable. If it is not, its status is automatically transitioned to canceled and your integration receives a source.canceled webhook event. Once a chargeable source is canceled, the customer’s authorized WeChat Pay payment is refunded automatically—no money is moved into your account. For this reason, make sure the order is canceled on your end and the customer is notified when you receive the source.canceled event.

    Additionally, pending sources are canceled after one hour if they are not used to authorize a payment, ensuring that all sources eventually transition out of their pending state to the canceled state if they are not used.

    Related resources

    Questions?

    We're always happy to help with code or other questions you might have! Search our documentation, contact support, or connect with our sales team. You can also chat live with other developers in #stripe on freenode.

    Was this page helpful? Yes No

    Send

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