Signup Process

Cutting straight to the point, let's look at how Marcellus Wallace would sign up. The particulars are covered in subsequent sections.

Payment Form Iframe

Managing PCI DSS compliance often presents significant challenges. That's where Billwerk+ Premium & Enterprise steps in – offering a straightforward solution for achieving compliance without the complexities typically involved in handling it independently. For more details about our paymentForm and other features, feel free to explore our resources.

Full Integration

Initializing SubscriptionJS

To start, load the SubscriptionJS library and initialize the basic objects required for the signup process. You'll need to provide your publicApiKey for identification. The providerReturnUrl is the URL where the customer will be redirected after completing payment on the payment provider's page (like PayPal).

Here's a basic setup example:

<script type="text/javascript" src="https://selfservice.sandbox.billwerk.com/subscription.js"></script>
<script type="text/javascript">
    var signupService = new SubscriptionJS.Signup();
    var paymentService = new SubscriptionJS.Payment({
            publicApiKey : "527cc4c951f45909c493c820",
            providerReturnUrl : "https://your_domain.com/your_finalize_page"
        },
        function () {  
            // Initialization complete, now you can process the order.
            // In a real implementation, you'd likely flag that initialization is complete.
            createOrder();
        },
        function() { // Error handling
            // Handle initialization errors here
        });
    // Note: SubscriptionJS.Payment is not ready immediately. Use the success callback to proceed with the order.
</script>

 

🚧

SubscriptionJS.Payment performs asynchronous initialization of the PSP (Payment Service Provider) specific JavaScript code. Do not commence the order process until the success callback is triggered.

The code segment below is provided as a simplified example, and it hardcodes data that customers would typically input via a form:

var cart = {
    "planVariantId": "527caacdeb596a247c6e0500"
};
var customer = {
    "firstName": "Marcellus",
    "lastName": "Wallace",
    "emailAddress": "[email protected]"
};
var paymentData = {
    "bearer": "CreditCard:Paymill",
    "cardNumber": "5169147129584558",
    "expiryMonth": "12",
    "expiryYear": "2017",
    "cardHolder": "Marcellus Wallace",
    "cvc": "311"
};

Step 1: Create the Order

The initial step in the subscription process is to create an order. The createOrder(...) function accepts the cart and customer data, along with success and error callbacks as parameters.

Here's an example function to create an order:

//Step 1: Create order
var createOrder = function()
{
    signupService.createOrder(cart, customer,
        pay, //Order created. Go on...
        errorHandler //Order could not be created
    );
}

The subscriptionJS system handles the initial step of creating a subscription order as depicted in the sequence diagram below.

Ensure that the handlers are properly implemented to provide a smooth user experience and to manage any issues that may arise during the order creation process.

Step 2: Commit the Order

After a successful order creation, the payment process is initiated. The paySignupInteractive(...) function requires paymentService, paymentData, and the order returned from the previous step, along with success and error callbacks. This step applies to free subscriptions as well and will complete the order process without initiating a payment.

📘

In practical scenarios, steps 1 (order creation) and 2 (order commitment/payment) should be implemented on separate pages. This separation ensures the order process is managed within the context of a single order.

Here's an example function for triggering the payment process:

// After order creation, initiate the payment process
var pay = function(order) {
    paymentService.paySignupInteractive(paymentService, paymentData, order,
        paymentHandler,// Payment succeeded, and the order is finalized.
        errorHandler, // Handle payment errors here
    );
} 

If step 2 is executed successfully, you'll encounter one of two scenarios:

Immediate Payment Completion

The payment is completed instantly without redirecting to a visible payment provider's page. This scenario is common for specific direct payment methods or free subscriptions.

Payment Provider Redirection

The customer is redirected to the payment provider's page (like PayPal checkout) to finalize the payment. After completing the payment on the payment service provider's (PSP's) checkout page, the customer is redirected back to the URL specified during the initialization in providerReturnUrl.

Here's an example illustrating how you might handle a successful return from step 2:

// After committing the order successfully
var paymentHandler = function (result) {
  if(!result.Url) {
      // The payment is completed without PSP interaction
      thankYou(); // Replace with your actual function to finalize subscribtion process
  } else {
      // If payment requires PSP interaction
      // The customer will be forwarded to the PSP's page and then back to providerReturnUrl
     window.location.href = result.Url; //Forward to PSP page to pay
  }
}
 

🚧

Caution! Special requirements apply when using Unzer as a payment method. Refer to the Unzer FAQ for details.

🚧

Caution! For PayEx CreditCard payments, be aware of a special case: If you're using our paymentForm, the input fields for Card Holder, Credit Card Number, CVC, and Expiry Date will not be displayed on your form. Instead, only the selected logos within the PayEx settings will be shown. The paySignupInteractive function will redirect your customer to the PayEx Credit Card Checkout Form, where these fields are required.

Error Handling and Payment Retries

In a real-world scenario, an error handler should provide user feedback based on the specific error code returned. For example, you may allow users to retry entering their credit card information if the initial submission was invalid. It's important to design an error handler that can interpret different error responses and guide the user accordingly.

var errorHandler = function(errorData) {
        alert("Subscription failed");
};
createOrder();

Moreover, paySignupInteractive may be invoked multiple times if previous payment attempts failed, ensuring that only one successful payment is processed for an order.

Preventing Double Submissions

Take measures to prevent the user from double-clicking the order button, as this can lead to multiple submissions and confusion, even though Billwerk+ Premium & Enterprise will handle the payments correctly. It's good practice to disable the order button after the first click or provide a visual indicator that the order is in process to enhance user experience and maintain a smooth order process.

Step 3: Finalize the Order

The finalize page is the concluding part of the order process, where you confirm the outcome of the customer's interaction with the payment provider. Upon the customer's return from the PSP's checkout, you need to call the SubscriptionJS.finalize(...) function with the appropriate success and error handling logic.

SubscriptionJS.finalize(success,error);

The SubscriptionJS.finalize function requires the same data structure as used in the initial example's step 3. It is critical to use the full, unaltered URL provided by the PSP, including all parameters, as SubscriptionJS depends on these parameters to properly finalize the order.

🚧

It's important to handle the finalization process carefully to ensure a smooth customer experience and to avoid any loss of transaction data due to URL parameter truncation.

The Simple Approach: Combining Steps 1 and 2

While SubscriptionJS offers the option to consolidate the creation and payment of an order into a single action; it's essential to understand the implications of this method. The simplicity of a single call with corresponding success and error handlers might seem appealing; however, this approach can introduce complications.

signupService.subscribe(paymentService, cart,  customer, paymentData,
    function (subscribeResult) {
        if (!result.Url)
            alert("success!"); //Successful subscription
        else
            window.location.href = result.Url; //Forward to PSP page to pay
        },
    function (errorData) {
        alert("something went wrong!");
    }
);

Considerations for Combining Order Creation and Payment:

  • Duplicate Orders: If customers navigate back and click the order button again, it could result in multiple orders and payments being inadvertently created.
  • Payment Data Corrections: There's no straightforward way to correct payment details if the customer enters them incorrectly, which could hinder the customer experience.

Best Practices:

We recommend using the step-by-step approach as demonstrated in the initial example, where order creation (Step 1) and order commitment/payment (Step 2). Sign are distinct actions. This method provides a more robust framework for managing the order process and minimizes the risk of duplicating orders or payments.

Guidance:

Do not resort to the simple approach when the preferred method of separate steps is feasible and applicable to your use case. The split-step method offers more control and is better suited to handle customer interactions effectively.