📍 Bolt Help / Developer Resources / Bolt SDKs / React Native SDK / Credit Card & 3D Secure
Credit Card & 3D Secure
Tokenize credit card details and handle 3D Secure verification using the Bolt React Native SDK for Embeddable Checkout.

Credit Card Payment

This guide covers credit card tokenization and 3D Secure for Bolt Embeddable Checkout. For the full backend API, see the Embeddable Checkout API Reference.

The Bolt React Native SDK tokenizes card data securely in a WebView loaded from connect.bolt.com. Card details never touch your app, keeping your integration PCI compliant.

Basic Flow

import { CreditCard, useThreeDSecure } from '@boltpay/react-native/payments';

function CheckoutScreen() {
  const cc = CreditCard.useController();
  const threeDSecure = useThreeDSecure();

  // Listen for field events
  cc.on('valid', () => setCanSubmit(true));
  cc.on('error', (msg) => setFieldError(msg));

  const handlePayment = async () => {
    // 1. Tokenize — returns TokenResult | Error (never throws)
    const result = await cc.tokenize();
    if (result instanceof Error) {
      console.error(result.message);
      return;
    }
    // result: { token?, last4?, bin?, network?, expiration?, postal_code? }

    // 2. Fetch 3DS reference ID — throws ThreeDSError on failure
    const referenceID = await threeDSecure.fetchReferenceID({
      token: result.token,
      bin: result.bin,
      last4: result.last4,
    });

    // 3. Send token to your backend to create the payment
    const paymentResponse = await yourApi.createPayment(result);

    // 4. Handle 3DS challenge if required — returns ThreeDSResult (never throws)
    if (paymentResponse['.tag'] === 'three_ds_required') {
      const challengeResult = await threeDSecure.challengeWithConfig(
        paymentResponse.id,
        {
          referenceID,
          jwtPayload: paymentResponse.jwt_payload,
          stepUpUrl: paymentResponse.step_up_url,
        }
      );
      if (!challengeResult.success) {
        console.error(challengeResult.error?.message);
      }
    }
  };

  return (
    <>
      <CreditCard.Component controller={cc} />
      <threeDSecure.Component />
      <Button onPress={handlePayment} title="Pay" />
    </>
  );
}

Step-by-Step Breakdown

  1. Create a controllerCreditCard.useController() returns a controller for the secure card input fields.
  2. Listen for events — Use cc.on() to react to valid, error, blur, and focus events on the card fields.
  3. Tokenize — Call cc.tokenize() to securely tokenize the card. This returns a TokenResult or an Error (it never throws).
  4. Fetch 3DS reference — Pass the token result to threeDSecure.fetchReferenceID() to get a reference ID for 3D Secure verification.
  5. Create payment — Send the token to your backend to initiate the payment via the Bolt API.
  6. Handle 3DS challenge — If the payment response indicates three_ds_required, call threeDSecure.challengeWithConfig() to present the challenge UI.

Credit Card Controller Methods

Method Description
tokenize() Returns Promise<TokenResult | Error>. Never throws.
on(event, callback) Register an event listener. Events: valid, error, blur, focus
setStyles(styles) Update input field styles after creation

3D Secure with a Stored Card

If you’ve already added a card via Bolt’s Add Card API and have a creditCardID, you can perform 3D Secure verification without re-tokenizing:

import { useThreeDSecure } from '@boltpay/react-native/payments';

function StoredCardPayment() {
  const threeDSecure = useThreeDSecure();

  const handlePayment = async (creditCardId: string, expiration: string) => {
    // Fetch 3DS reference using stored card ID
    const referenceID = await threeDSecure.fetchReferenceID({
      id: creditCardId,
      expiration,
    });

    // Create payment on your backend with the 3DS reference
    const paymentResponse = await yourApi.createPayment({
      creditCardId,
      referenceID,
    });

    // Handle 3DS challenge if required
    if (paymentResponse['.tag'] === 'three_ds_required') {
      const result = await threeDSecure.challengeWithConfig(
        paymentResponse.id,
        {
          referenceID,
          jwtPayload: paymentResponse.jwt_payload,
          stepUpUrl: paymentResponse.step_up_url,
        }
      );
      if (!result.success) {
        console.error(result.error?.message);
      }
    }
  };

  return <threeDSecure.Component />;
}

3D Secure Methods

Method Description
fetchReferenceID(creditCardInfo) Accepts a TokenResult or CreditCardId. Returns Promise<string>. Throws ThreeDSError on failure.
challengeWithConfig(orderToken, config) Presents the 3DS challenge UI. Returns Promise<ThreeDSResult>. Never throws — check result.success.

3D Secure Error Codes

Code Description
1001 Credit card id or token must be supplied
1002 Credit card id and token cannot both be supplied
1003 Malformed credit card token
1004 Order token does not exist
1005 API response error during verification
1006 Verification not required
1007 Setup error during verification
1008 Authentication failed
1009 Failed to create challenge or challenge failed
1010 Failed to get device data collection jwt
sdk react-native credit-card 3ds payments