Setup payment method and create subscriptions

A step-by-step guide for setting up payment methods and creating subscriptions using the OpenPay SDK and OpenPay.js

This is to be used when you want to collect payment method first and then create a subscription later time. If you want to accept payments and directly create subscription in one simple form please see this guide.

Create subscriptions via checkout

This is for when you want to accept payments and directly create subscriptions in one simple form.

Step 1: Create a secure checkout tokenCopied!

First, you need to create a Checkout Session using the checkout.create_checkout_session method via the OpenPay SDK in the backend.

You can configure the session according to your specific requirements, such as defining the mode of the checkout session. In this case, since we only want to save the payment method (and will create subscriptions later), we'll use SETUP mode.

For detailed API references, please refer to the API documentation.

Here’s an example of how to generate a secure checkout session:

# Setup Mode
checkout = op_client.checkout.create_checkout_session(
    CreateCheckoutSessionRequest(
      customer_id=customer_id,   # (Optional) To create session specific customer
      line_items=[],             # No line items for setup mode
      mode=CheckoutMode.SETUP,   # Setup mode for saving payment info
    )
)
secure_token = checkout.secure_token  # Token to be passed to the frontend
// JavaScript Example
const checkoutSession = await apiClient.checkoutApi.createCheckoutSession({
  createCheckoutSessionRequest: {
    mode: CheckoutMode.Setup,
    lineItems: [],
    currency: CurrencyEnum.Usd, 
  }
})

const secureToken = checkoutSession.secureToken;

Once the secure_token is generated, it’s ready to be used on the frontend to securely collect payment details. Pass this token to the OpenPayForm constructor in your frontend app to handle the payment setup.

Step 2: Implement the payment formCopied!

Use the OpenPayForm class to construct a secure form where customers can enter their payment details. The form operates the same way as a subscription form, but it only saves the payment method for future use.

Pure Js Implementation Example - in your frontend, you can now render the form like this:
// Initialization
const openPayForm = new OpenPayForm({
  checkoutSecureToken: 'checkout-secure-token-uuid',   // Token from Step 1
  formTarget: '#payment-form',
  onChange: () => setError(undefined),              
  onLoad: onLoad,                                       // Called when the form is loaded
  onValidationError:(message) => setError(message),     // Handle form validation errors
  onSetupPaymentMethodSuccess: (paymentMethodId) => {   // Callback for successful setup
    console.log("Payment Method ID:", paymentMethodId)  // Use the saved payment method ID
  },
  onCheckoutError: onCheckoutError,                     // Handle any checkout errors
})
// Elements 
openPayForm.createElement('card').mount('#card-element');// Create and renderthe card element

// Submission
document.querySelector('#submit')?.addEventListener('click', () => {
    openPayForm.submit();
});

HTML

<body>
  <div id="payment-form">
    <div class="billing-details">
         <label>
              <span>First Name</span>
              <input data-opid="firstName" placeholder="First Name" />
         </label>
         <label>
              <span>Last Name</span>
              <input data-opid="lastName" placeholder="Last Name" />
         </label>
         <label>
              <span>Email</span>
              <input data-opid="email" placeholder="Email" />
         </label>
         <label>
              <span>Promotion Code</span>
              <input data-opid="promotionCode" placeholder="Promotion Code" value="" />
         </label>
      	 <label>
              <span>Zip Code</span>
              <input data-opid="zipCode" placeholder="Zip Code" />
         </label>
         <label>
              <span>Country</span>
              <input data-opid="country" placeholder="Country" />
         </label>
      </div>
    <div id="card-element"></div>
    <button id="submit" type="button">Pay</button>
  </div>  
</body>

Key callbacks and props:

  • checkoutSecureToken: The secure token generated from the backend to link the session.

  • onSetupPaymentMethodSuccess: A callback that returns the paymentMethodId after the setup process is successful.

  • onValidationError: Handles any validation errors from the form fields.

  • onCheckoutError: Handles any errors during the setup process.

For detailed props and callbacks, please refer to the main guide:

Guide (.js)

Integrating payment elements

Note (For using staging environment for testing purpose) - please provide baseUrl prop with our staging environment. baseUrl is default to our production environment.

Example:

new OpenPayForm({
   baseUrl: isStagingEnv ? "https://cde.openpaystaging.com/": undefined
})

Step 3: Authorize payment method (optional)Copied!

After the customer successfully saves their payment method, the onSetupPaymentMethodSuccess callback is triggered. This callback provides a paymentMethodId, which can be sent to the backend for authorization.

To authorize the saved payment method, use the payment_methods.authorize_payment_method method via the OpenPay SDK.

For detailed API references, see Authorize Payment Method.

Authorizing Payment Method Example:
# Authorize the payment method
request = AuthorizePaymentMethodRequest(
   payment_method_id=payment_method_id,
   authorize_amount_atom=randint(5_00, 55_00),  # Random authorization amount
   currency=CurrencyEnum.USD
)

pm_external = client.payment_methods.authorize_payment_method(request)
// JavaScript Example
const request = {
  paymentMethodId: paymentMethodId,
  authorizeAmountAtom: 5_00, // Amount in cents (e.g., $5.00)
  currency: CurrencyEnum.Usd,
};

const authorized = await apiClient.paymentMethodsApi.authorizePaymentMethod({
  authorizePaymentMethodRequest: request,
});

Step 4: Create a subscriptionCopied!

Once the payment method is successfully saved, you can use the paymentMethodId to create a subscription for the customer.

To create a subscription, use the subscriptions.create_subscriptions method via the OpenPay SDK.

For detailed API references, see Create Subscription.

Creating a Subscription Example:
# Create a subscription request
create_request = CreateSubscriptionRequest(
  customer_id='TODO_TARGET_CUSTOMER_ID',
  payment_method_id='TODO_CREATED_PAYMENT_METHOD',
  selected_product_price_quantity=[
    SelectedPriceQuantity(price_id=price.id, quantity=initial_quantity)
  ],
  total_amount_atom=initial_quantity * price.unit_amount_atom,
  coupon_id='TODO_OPTIONAL_COUPON',  # Optional
)

# Create the subscription
sub_create_res = client.subscriptions.create_subscriptions(create_request)
// JavaScript Example
const selectedPriceQuantity = [
  {
    priceId: price.id,
    quantity: initialQuantity,
  },
];

const request = {
  customerId: customer_id,
  couponId: coupon_id,  // Optional
  selectedProductPriceQuantity: selectedPriceQuantity,
  totalAmountAtom: initialQuantity * price.unitAmountAtom,
};

const subscriptionResponse = await apiClient.subscriptionsApi.createSubscriptions({
  createSubscriptionRequest: request,
});