Checkout with FPX payments

    Use Checkout to accept FPX payments, a common payment method in Malaysia.

    Stripe users in Malaysia can accept one-time FPX payments using Checkout.

    Customers pay with FPX by redirecting away from a Checkout Session to their bank, sending you payment, and then returning to Checkout.

    Follow these steps to modify your existing Checkout client & server integration to create a Checkout page that accepts cards and FPX for one-time payments.

    1. Enable FPX in the Stripe Dashboard
    2. Create a Checkout Session which accepts FPX payments
    3. Redirect to Checkout

    Step 1: Enable FPX in the Stripe Dashboard

    In order to accept FPX payments via Checkout, you must first enable FPX in the Stripe Dashboard and accept the FPX terms of service. Doing so requires an activated Stripe Account.

    Step 2: Create a Checkout session which accepts FPX payments

    When creating a Checkout Session, you must specify which payment methods you want to accept using the payment_method_types argument. Possible values for this argument are currently card, ideal, and fpx.

    Checkout Sessions use line_items to represent a list of items the customer is purchasing. Each line item must have a currency, and all line items in a given session must share the same currency. Specify MYR (currency code myr) for all line items if you wish to accept FPX payments.

    The following example code demonstrates how to create a Checkout session that accepts both card and fpx payments for a single item.

    curl https://api.stripe.com/v1/checkout/sessions \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d "payment_method_types[]"=fpx \ -d "line_items[][name]"=T-shirt \ -d "line_items[][description]"="Comfortable cotton t-shirt" \ -d "line_items[][images][]"="https://example.com/t-shirt.png" \ -d "line_items[][amount]"=2000 \ -d "line_items[][currency]"=myr \ -d "line_items[][quantity]"=1 \ -d success_url="https://example.com/success?session_id={CHECKOUT_SESSION_ID}" \ -d cancel_url="https://example.com/cancel"
    # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = Stripe::Checkout::Session.create({ payment_method_types: ['card', 'fpx'], line_items: [{ name: 'T-shirt', description: 'Comfortable cotton t-shirt', images: ['https://example.com/t-shirt.png'], amount: 2000, currency: 'myr', quantity: 1, }], success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', })
    # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' session = stripe.checkout.Session.create( payment_method_types=['card', 'fpx'], line_items=[{ 'name': 'T-shirt', 'description': 'Comfortable cotton t-shirt', 'images': ['https://example.com/t-shirt.png'], 'amount': 2000, 'currency': 'myr', 'quantity': 1, }], success_url='https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url='https://example.com/cancel', )
    // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card', 'fpx'], 'line_items' => [[ 'name' => 'T-shirt', 'description' => 'Comfortable cotton t-shirt', 'images' => ['https://example.com/t-shirt.png'], 'amount' => 2000, 'currency' => 'myr', 'quantity' => 1, ]], 'success_url' => 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' => 'https://example.com/cancel', ]);
    // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; Map<String, Object> params = new HashMap<String, Object>(); ArrayList<String> paymentMethodTypes = new ArrayList<>(); paymentMethodTypes.add("card"); paymentMethodTypes.add("fpx"); params.put("payment_method_types", paymentMethodTypes); ArrayList<HashMap<String, Object>> lineItems = new ArrayList<>(); HashMap<String, Object> lineItem = new HashMap<String, Object>(); lineItem.put("name", "T-shirt"); lineItem.put("description", "Comfortable cotton t-shirt"); lineItem.put("amount", 2000); lineItem.put("currency", "myr"); lineItem.put("quantity", 1); lineItems.add(lineItem); params.put("line_items", lineItems); params.put("success_url", "https://example.com/success?session_id={CHECKOUT_SESSION_ID}"); params.put("cancel_url", "https://example.com/cancel"); Session session = Session.create(params);
    // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); (async () => { const session = await stripe.checkout.sessions.create({ payment_method_types: ['card', 'fpx'], line_items: [{ name: 'T-shirt', description: 'Comfortable cotton t-shirt', images: ['https://example.com/t-shirt.png'], amount: 2000, currency: 'myr', quantity: 1, }], success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}', cancel_url: 'https://example.com/cancel', }); })();
    // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.CheckoutSessionParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", "fpx", }), LineItems: []*stripe.CheckoutSessionLineItemParams{ &stripe.CheckoutSessionLineItemParams{ Name: stripe.String("T-shirt"), Description: stripe.String("Comfortable cotton t-shirt"), Amount: stripe.Int64(2000), Currency: stripe.String(stripe.CurrencyMYR), Quantity: stripe.Int64(1), }, }, SuccessURL: stripe.String("https://example.com/success?session_id={CHECKOUT_SESSION_ID}"), CancelURL: stripe.String("https://example.com/cancel"), } session, err := session.New(params)
    // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new SessionCreateOptions { PaymentMethodTypes = new List<string> { "card", "fpx", }, LineItems = new List<SessionLineItemOptions> { new SessionLineItemOptions { Name = "T-shirt", Description = "Comfortable cotton t-shirt", Amount = 2000, Currency = "myr", Quantity = 1, }, }, SuccessUrl = "https://example.com/success?session_id={CHECKOUT_SESSION_ID}", CancelUrl = "https://example.com/cancel", }; var service = new SessionService(); var session = service.Create(options);

    Step 3: Redirect to Checkout

    Modifying an existing Checkout integration to accept FPX payments requires no changes to your website frontend code. Call redirectToCheckout and provide the Checkout Session id as a parameter to begin the payment process.

    See one-time payments with Checkout for more details about this step.

    FPX-specific considerations

    Determining which payment methods to display

    Using the payment_method_types argument, it’s possible to specify any combination of card and fpx for a given Checkout session. Your application logic determines which payment methods to make available. For example, you might only display FPX for customers located in Malaysia.

    Beware that if you create Checkout sessions that only support FPX and not cards, customers without a compatible bank account won’t be able to pay.

    Compatibility

    To support FPX payments, a Checkout Session must satisfy both of the following conditions:

    • Only one-time line items can be used (recurring subscription plans are not supported)
    • Prices for all line items must be expressed in MYR (currency code myr)

    Testing

    To test FPX in your test mode Checkout integration, enter any email address and name, and select any FPX bank from the menu. Clicking Pay redirects you to a Stripe-hosted FPX test payment page where you can either authorize or fail the test payment.

    This is unlike cards, which require a specific Stripe test card number to test.

    Disputed payments

    FPX payments have a low risk of fraud or unrecognized payments because the customer must authenticate the payment with their bank. Therefore, there is no dispute process that can result in a chargeback and funds withdrawn from your Stripe account.

    FPX requirements

    Payment confirmation page

    The Checkout Session created in Step 2 contains a reference to PaymentIntent object. Use this ID to retrieve a PaymentIntent and extract the necessary fields for payment confirmation page.

    The following information must be displayed on the payment confirmation page that your customer returns to after completing their bank authentication. You can access this information on the Charge object. You can retrieve the Charge object from the payment_intent.succeeded webhook event or directly from the PaymentIntent object.

    Information Source of information
    Transaction Date & Time created from the Charge object.
    Amount amount from the Charge object.
    Seller Order No. statement_descriptor from the Charge object.
    FPX Transaction ID payment_method_details[fpx][transaction_id] from the Charge object.
    Buyer Bank Name payment_method_details[fpx][bank] from the Charge object
    Transaction Status status from the Charge object

    Next steps

    Congrats! You now have a complete Checkout integration for one-time payments with cards and FPX.

    Was this page helpful?

    Feedback about this page?

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

    On this page