B2B(Aura) Hosted Payment Page Integration
This post is about doing a hosted payment page integration for B2B(Aura).
Summary
Introduction
In this post, I will be showing how to integrate a payment service provider with Salesforce B2B(Aura). This will be a hosted payment page(HPP) integration. As part of standard B2B checkout, the B2B store hosts the credit card(CC) form on the website itself. In this scenario, a customer enters the CC information on the website and completes the payment on the SF B2B store and thus never leaves the B2B store.
A hosted payment page is a web page, hosted by a third-party payment provider, that provides secure checkout capabilities. In this scenario, the customer is redirected to a third party hosted webpage to complete the payment, and after successful payment customer is redirected back to the B2B store.
Note: If you are looking for standard payment integration you can use Stripe integration for reference and similary for client side payment integration you can use Stripe client side integration for reference.
We will integrate a Turkish PSP called Iyzico. The approach outlined below can be easily implemented for any other PSP.
Github Repository - https://github.com/garran89/b2b-aura-iyzico-hpp
Iyzico Documentation
On a high level, the following steps are needed to do an HPP integration with B2B.
- Register a Payment Gateway Provider. This step is common between HPP and non-HPP integrations.
- Replace the standard payment method LWC screen component with a custom payment method component.
- Call the Payment Gateway API to retrieve the HPP redirect URL.
- Redirect the customer to the Payment Gateway HPP page.
- Create a new Checkout SubFlow to handle the callback from Payment Gateway back to the B2B store.
Registering a Payment Gateway Provider(PGP)
The steps to register a PGP are outlined in the official documentation.
- See Named Credentials for the Iyzico named credential.
- Use IyzicoPaymentAdaptor Apex Class to insert a new PaymentGatewayProvider record.
Payment Method Component
Out of the box, B2B(Aura) comes with a payment method component that support Purchase Order and Credit Card form component. We will replace the standard component with our own custom LWC component called payWithIyzico. This component is responsible for the following operations:
- Display a
Pay with Iyzico
button. - Make an API call to Iyzico to retrieve the HPP redirect URL.
- Setting the
CartHandling__c
custom field on Cart object to “redirect”. We use this value to handle the callback from Iyzico back to B2B store.We execute the correct subflow based on this field value. - Redirecting the customer to the Iyzico HPP.
This component calls the Iyzico CheckoutForm Initialize API. This API returns in response the paymentPageUrl
. This is the URL of the Iyzico HPP page. The LWC components redirect the customer to this page.
Iyzico callback Subflow (Subflow - Iyzico Callback)
After the customer enters their CC information on the Iyzico HPP, Iyzico sends the customer back to the B2B store. This redirection happens with the help of a callbackUrl
. The callbackUrl is passed to Iyzico as part of the CheckoutForm Initialize API
call in the previous step. We use the standard checkout
URL as a callbackUrl. E.g. https://site.com/storeId/s/checkout/cartId
. Iyzico makes a POST request to this callbackUrl with a token
. This POST request is automatically converted to a GET request by salesforce platfom via 301 redirect. So, the final URL becomes https://site.com/storeId/s/checkout/cartId?token=myToken
. The token is needed to retrieve the payment status.
Once, the customer is redirected back to the B2B checkout URL, the standard B2B Checkout flow will intercept the redirect. This checkout flow will call the Subflow - Iyzico Callback to handle the redirect. Standard B2B Checkout flow will make use of the CartHandling__c
custom field to decide whether to call the Iyzico subflow or not.
This subflow renders a LWC component iyzicoHandleHPP. This component is responsible for the following operations:
- Display the
Please wait while we process your payment
message to the customer. - Make an API call to Iyzico to get the payment status of the order. It uses the returned token and the cartId to get the payment status.
- Call the handlePostAuthorization method from the IyzicoController. This method is responsible for handling the pre-authorized transaction.
A custom LWC component is needed because it is not possible to set a checkout flow input variable based on a URL parameter(token=myToken
). In an ideal scenario, we would set a flow input variable based on a URL parameter and then have an apex class to do API calls to Iyzico but unfortunately, checkout flows don’t support this so we have to use a custom LWC component as a workaround. The LWC component extracts the token from the URL parameter and then makes a call to an apex controller.
The LWC components calls the Iyzico CheckoutForm Retrieve API. This API returns the status of the payment. The LWC component then makes use of the standard Salesforce connect payment APIs to handle the payment status. The standard payment class methods automatically calls the appropriate methods of the registered payment gateway provider Apex class.
In the standard payment integration, the authorization happens on the B2B store itself by calling the PSP authorization APIs. For such integrations, we use the authorise method of the payment class. This method along with other information needs cardPaymentMethod object. In standard payment integration, we have payment card information easily available with us as customers enters CC information on the B2B store itself.
In HPP scenario, we cannot use authorise
method because of the following reasons
- There is no explicit authorization in case of HPP. The implicit authorization happens after customer enters CC information on HPP but before the customer is redirected back to B2B store.
- As explained above
authorise
method requirescardPaymentMethod
information. In case of HPP, we don’t have this information as CC information is entered on the 3rd party website. One possible workaround here is to use dummy card information.
Instead, We use postAuth payment class to handle the pre-authorized transaction.The postAuth
method also allow us to use AlternativePaymentMethod class thus not requiring us to create dummy cardPaymentMethod
objects.
So, we saw how we can integrate a Hosted Payment Page solution with Salesforce B2B(Aura).
Note: This post is based on another blog post by Salesforce.