Create subscriptions via checkout

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

If you want to break it out into two steps where you collect payment method first and then later create a subscription please see this guide:

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

Step 1: Create a secure checkout tokenCopied!

First, you'll need to create a Checkout Session with mode: 'SUBSCRIPTION'. This will result in checkout session information that contains a secure_token to be used in the next steps

Example - here’s how to generate a secure checkout session using mode: 'SUBSCRIPTION':

 response = self.client.checkout.create_checkout_session(
      CreateCheckoutSessionRequest(
        customer_id='TODO_TARGET_CUSTOMER_ID', # (Optional), # (Optional)
        customer_email=None,
        line_items=[
          CreateCheckoutLineItem(price_id='TODO_DESIRED_PRICE_1', quantity=2),
          CreateCheckoutLineItem(price_id='TODO_DESIRED_PRICE_2', quantity=3),
        ],                               
        currency=CurrencyEnum.USD,
        mode=CheckoutMode.SUBSCRIPTION, 
        return_url=RETURN_URL,
        success_url=SUCCESS_URL,
      )
    )

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

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 the frontend, you can now render the form like this:

Javascript

// Initialization
const openPayForm = new OpenPayForm({
  checkoutSecureToken: 'checkout-secure-token-uuid',   // Token from Step 1
  formTarget: '#payment-form',
  baseUrl: ""
  onChange: () => setError(undefined),              
  onLoad: (amountAtm, currency) => {
  	hideLoading()
    showAmount(format(amountAtm, currency))
  },                                                    // Called when the form is loaded
  onValidationError:(message) => setError(message),     // Handle form validation errors
  onCheckoutSuccess: (invoiceUrls, subscriptionIds, customerId ) => {   // Callback for successful checkout
    // handle successful checkout
  },
  onCheckoutError: onCheckoutError,                     // Handle any checkout errors
})
// Elements 
openPayForm.createElement('card').mount('#card-element');// Create and render the 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.

  • onLoad: Triggered when the checkout form is successfully loaded. It includes totalAmountAtoms and currency.

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

  • onCheckoutSuccess: A callback that returns the invoiceUrls, subscriptionIds and customerId after the checkout process is successful.

  • onCheckoutError: Handles any checkout error during the process.

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

Guide (.js)

Integrating payment elements

Note if you are testing in staging/sandbox - set baseUrl prop to point to our sandbox environment, baseUrl defaults to our production environment.

Example:

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

Step 3: Handling a successful checkoutCopied!

Once the customer successfully checkout with their payment method, the onCheckoutSuccess callback is triggered. The callback returns the invoiceUrls, subscriptionIds and customerId.

  • Invoice urls can be used to display invoices or redirect to invoice page

  • Subscription IDs can be used for further processing with OpenPay SDK

  • Customer ID is the created customer on OpenPay side during checkout process. If you are creating the checkout session for specific customer, it will return that specific customer ID