Overview

BillwerkJS offers a lightweight, easy-to-use gateway so you can implement your payment, signup and customer self-service forms seamlessly in your own website. BillwerkJS doesn't have any external dependencies, weighs in at only a few kB, and doesn't meddle with your DOM (except for loading PSP-specific javascript, if required). Essentially, it's a Javascript SDK for BillwerkJS that hides cross-origin complexity.

Because of its design, BillwerkJS is compatible with any frontend framework such as AngularJS, EmberJS, knockout or simply jQuery.

Essentially, BillwerkJS consists of these three modules:

Signup
Handles the signup of new customers. These operations can be performed for anonymous users and consequently, don't require any form of identification or authentication. Signup also provides functionality to calculate a detailed pricing information based on the cart and customer data (tax depends on country and vat id). A signup includes registration of the new customer and the subscription in billwerk.
For data security reasons the publically accessible signup does not check for existance of a customer. Consequently, all subsequent subscriptions of a single customer will create a new customer object.
If you want to allow customers to subscribe several times you have to provide a separate order process from within your customer's authenticated account.
Currently, BillwerkJS does not provide a corresponding helper method. Please take a look at our REST API documentation on how to create such an order. The rest of the order process is covered in BillwerkJS.
Portal
Contains methods that help you create a portal for your customers.
  • View current plan
  • Modify personal data: name, address, ...
  • Change payment data: provide new CC, change payment method, ...
  • Up-/Downgrade: BillwerkJS provides helpers to commit an up-/downgrade order. The order has to be created using the billwerk API. Details
  • Order additional components (in conjunction with up-/downgrades)
  • Cancel a contract
  • Download invoices
Since these methods allow fetching / modifying contract information and personal data, they require a customerToken that you have to acquire through a regular API call from your backend. The token has a limited lifetime.
Please note all functions are contract based. You need to acquire a separate token for each contract.
Payment
Puts an abstraction on payment service providers. While this is the most complex module internally, it also has the simplest API. Usually, all you need to do is construct this object and pass it to the BillwerkJS.Signup or BillwerkJS.Portal methods that require payment.

Sandbox Environment

Billwerk provides two completely separate and independent billwerk instances, the Sandbox and the Live System.
Use the Sandbox for all your integration development. Please signup -> here <- for a free sandbox account.
After signup for testing purposes you can begin integration by loading BillwerkJS like this:

<script type="text/javascript" src="https://sandbox.billwerk.com/selfService/billwerkJS"></script>
For payment processes you will also need to pass a public API key:
paymentService = new BillwerkJS.Payment({ publicApiKey : "527cc4c951f45909c493c820" }...
This key can be found within the self service settings of your billwerk Admin UI.

Important! Please note the billwerk Sandbox is almost an exact copy of the Live System. This means you need to be careful with your test data. Emails will be sent and real payments can be triggered for some PSPs. Make sure to use email addresses you own and configure your PSPs to just simulate payments.

Subscriptions

Let's cut to the chase. Here's an example of a Marcellus Wallace signing up. Details will be dicussed in the following sections.

Load billwerkJS and initialize basic objects. For identification you need to provide your publicApiKey. The providerReturnUrl specifies a page on your website a customer returns to after payment on a payment provider page (e.g. PayPal).

<script type="text/javascript" src="https://sandbox.billwerk.com/selfService/billwerkJS"></script>
<script type="text/javascript">
    signupService = new BillwerkJS.Signup();
    paymentService = new BillwerkJS.Payment({ 
            publicApiKey : "527cc4c951f45909c493c820",
            providerReturnUrl : "https://your_domain.com/your_finalize_page"
        }, 
        function () { 
            /*Everything initialized so we can go on...  
              Start processing order, because example does not have a form.
              In real life you would probably set a flag that initialization is finished.*/
            createOrder();
        }, 
        function() { /*error*/ });
    // Important! BillwerkJS.Payment not necessarily ready here. Use success callback to go on in order process
Important! BillwerkJS.Payment does asynchronous initialization of the PSP specific JS code. Do not start order process until success callback is called!

The following section is hardcoding data that would usually be entered by the customer within a form. This is just for simplicity of the example.

    var cart = {
        "planVariantId": "527caacdeb596a247c6e0500"
    };
    var customer = {
        "firstName": "Marcellus",
        "lastName": "Wallace",
        "emailAddress": "mhw@example.com"
    };
    var paymentData = {
        "bearer": "CreditCard:Paymill",
        "cardNumber": "5169147129584558",
        "expiryMonth": "12",
        "expiryYear": "2017",
        "cardHolder": "Marcellus Wallace",
        "cvc": "311"
    };

The first step in the subscription process is creating an order. The function createOrder(...) takes the cart and customer data, as well as a success and error callback.

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

After successful creation of the order the payment process is triggered. The function paySignupInteractive(...) takess paymentService, paymentData and the order that was returned in the last step. You also pass a success and error callback.
This step is also done for free subscriptions. It'll simply finish the order process without triggering any payment.

In a real world integration step 1 (order creation) and 2 (order commit / payment) should be implemented on separate pages to be able to handle the order process within the context of a single order.
    //Step 2: Trigger payment / order commit
    var pay = function(order) {
        signupService.paySignupInteractive(paymentService, paymentData, order,
            paymentHandler, //Everything ok so far. Go on...
            errorHandler //Payment failed
        );
    };

If step 2 returned successfully there are two possible use cases.

  1. The payment could already be finished without a visible payment provider page.
  2. The payment process requires the customer to be forwarded to the payment provider page (e.g. PayPal checkout). After the payment PSPs checkout page the customer will be forwarded to the Url you specified during initialization in providerReturnUrl

    //Step 3: Forward to PSP page if not already finished
    var paymentHandler = function (result) {
        if (!result.Url)
            alert("success!"); //Successful subscription
        else
            window.location.href = result.Url; //Forward to PSP page to pay
    }

The rest of the example is a very simple error handler and a call executing the example. In a real world error handler you'd probably do handling based on the error code returned, e.g. let the user change credit card number if it was invalid. You can call paySignupInteractive several times if privious payments failed. Billwerk will take care that only a single successful payment is processed for an order.

Beware the user from double clicking the order button. Billwerk will still handle the payments correctly, but it would most probably produce undesired effects in your order process.
    var errorHandler = function(errorData)
    {
        alert("Subscription failed");
    };
    createOrder();

</script>

Finalize page

As shown in the last examples some payment provider integrations involve forwarding to the PSP's checkout page. The PSP will forward the user to the Url you provided in providerReturnUrl after the customer has finished checkout. This Url is called the finalize page. It is the last page of the order process. On this page you need to call the billwerkJS function finalize(...). The data structure passed to the functions is the same as in step 3 of the initial example.

BillwerkJS.finalize(success,error);
Don't truncate the Url parameters used by the PSP. BillwerkJS needs this information.

The simple approach

BillwerkJS also provides a way to combine step 1 and 2 of the initial example. In this case you just need a single call, a success and an error handler.

    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!");
        }
    );
</script>

Its simplicity may be tempting, but combining order creation and payment in a single step can lead to serious problems if not handled correctly. Customers could easily end up placing two or more orders by going back in the order process and clicking the order button a second or third time. Each click will produce a separate order and payment. You also can't offer a convenient way to change payment data, if the customer made a mistake. We strongly encourage you to use the approach with separated order creation and order commit / payment you saw in the first example.

Don't use the simple approach if the preferred approach of separated steps is applicable for you.

Payments / Payment Service Providers (PSPs)

Several customer interactions involve payments. billwerk offers integration with different payment providers. BillwerkJS hides most of the complexity so integrating any supported providers is done with the same approach.

We also offer a payment method that does not involve any payment provider. On account payments can be used if a customer should be able to transfer money manually from his bank account after an invoice was received. To use this payment method you need to pass "InvoicePayment" as payment provider.

If a customer should not be required to pass payment information upon subscription, you can pass "None:None" as payment provider. This is only allowed for plan variants which permit subscriptions without payment information (flag 'allow signup without payment information'). A use case could be that you offer a trial period and want the user to pass payment information not until trial period has expired.
In some use cases it could also be suitable for up-/downgrades.

Nevertheless, let's begin with a basic payment workflow with a transparent PSP.

We distinguish between 'interactive' and 'non interactive' payments. 'Interactive' means a customer interactively enters his payment data like credit card or bank account information. In billwerk the most prominent use case for this kind of payment is the initial signup.
Usually upgrading a subscription involves a 'Non Interactive' payment. Payment information has already been provided during signup and will be reused for the upgrade.

'Interactive' payments

Interactive payments require two objects. We need to create an BillwerkJS.Payment instance and an object representing the payment data. The payment data object contains the selected payment method / provider and additional payment information like credit card data, if required for the payment method.

paymentService = new BillwerkJS.Payment({ publicApiKey : "527cc4c951f45909c493c820" }, 
    function () { /*ready*/ }, 
    function() { /*error*/ });
var paymentData = {
    "bearer": "CreditCard:Paymill",
    "cardNumber": "5169147129584558",
    "expiryMonth": "12",
    "expiryYear": "2015",
    "cardHolder": "Marcellus Wallace",
    "cvc": "911"
};
    
Both objects just need to be passed to the corresponding BillwerkJS method representing the desired action.

Paying a subscription signup

signupService.paySignupInteractive(billwerkJSPayment, secretPaymentData, order, success, error);

Paying an upgrade interactively

portalService.upgradePayInteractive (paymentService, paymentData, order, success, error);

Changing the payment method

portalService.paymentChange(paymentService, paymentData, success, error);

Credit Card Data, PCI-DSS

As you can see from the sample, the credit card data will be known to your own javascript. Make sure that this information is not logged and never sent to your server! BillwerkJS will hand off any PCI-DSS protected data to the selected PSP so the data is sent from the customer's browser directly to the PSP, thus keeping you from PCI-DSS hassle.

Of course, it is important to deliver the form itself via HTTPS to prevent third parties from tampering with the form. BillwerkJS is also only available via HTTPS.

Integrating payment processes with PSP redirects

This part is mandatory for black-label and white-label providers. Even though white-label providers are usually transparent, there are processes that include redirects to the PSP, e.g. credit card payments with 3D secure. Let's take a look at another signup process. This time we want to integrate PayPal.

paymentService = new BillwerkJS.Payment({
        publicApiKey : "527cc4c951f45909c493c820", 
        providerReturnUrl : "https://your_domain.com/your_finalize_page"
    }, 
    function () { /*ready*/ }, 
    function() { /*error*/ }
);
var paymentData = {
    "bearer": "PayPal",
    "emailAddress": "test@example.com" /*If not passed, billwerk will use the customer's signup email address*/
};
signupService.subscribe(paymentService, cart,  customer, paymentData, 
    function(data) {
        if (data.Url) {
            // Open the PSP URL if provided
            window.location.href = data.Url;
        }
        else {
            // No PSP page to open here
        }
    }
, error);
First please have a look at the success callback in this example. If calling subscribe() succeeded it will return a URL that leads to the PSP checkout page. Open it to let the customer go on with the payment.
Now take a look at the initialization of BillwerkJS.Payment. There is an additional parameter named providerReturnUrl. This URL is passed to the PSP. When the customer finished his payment he might be redirected to this URL. This page is used to finalize the order and show the customer a succes or error message. The required BillwerkJS code on this page is a single call:
BillwerkJS.finalize(success,error);
Except for the mandatory success and error callback no parameters need to be passed. The PSP added some URL encoded parameters which BillwerkJS passes to the billwerk server. It'll trigger order finalization as subscribe() would do for white label providers.
It is not certain that the order process ever reaches the finalize page, e.g. a customer could simply close the browser after successful payment. Therefore, as a second way of payment confirmation billwerk is notified by the PSP which will trigger the same processes as BillwerkJS.finalize().

'Non Interactive' payments

A good example is upgrading a subscription. Although BillwerkJS provides a way to pay upgrades interactively, usually payment is done implicitely with the payment bearer stored for the subscription.

    portalService.upgradePaySync(orderId,success,error);
As you can see for non interactive payments no payment information needs to be passed.
Non interactive payments are also triggered by billwerk transparently for each recurring payment.

Up- and Downgrades

For security reasons, you can't actually perform the up/downgrade solely through the frontend. Instead, you'll have to create an order from your backend using the REST API. Please read here.

You'll want to ensure that up- or downgrades requested by the user are actually valid. For instance, a downgrade might not be allowed at this time or in conjunction with a given component that the customer is subscribed to. Since this type of business logic can generally be very complex, it makes sense to have the implementation on your side.

To pay and finalize the order call BillwerkJS.Portal.upgradePaySync(...). In this case the conract's current payment bearer will be used.

If your implementation allows providing new payment data use BillwerkJS.Portal.upgradePayInteractive(...) instead.

Coupons

To grant a discount you can offer Coupon Codes to your customers. A single Coupon Code can be passed with each subscription or up-/downgrade order.

A Coupon Code is passed in the Cart object.

var cart = {
    "planVariantId": "527caacdeb596a247c6e0500",
    "couponCode": "ACB-123"
};
        

Coupon Code validation

The Cart object can be passed several BillwerkJS methods. If the Coupon Code is invalid an error with the code InvalidCouponCode will be returned.

The Preview() method is an exception. It'll return an Order object in either case. It contains the sub object Coupon with detailed information.

Valid Code passed to Preview()

{
    "Order" : {
        "Coupon":{
            "CouponCode":"ABCDEF",
            "CouponId":"55d31a7d68a44f270478425d",
            "DiscountId":"55d31a4e68a44f2704784259"
        },
        ...
    }
}
        

Invalid Code passed to Preview()

{
    "Order" : {
        "Coupon":{
            "CouponCode":"ABCDEF",
            "ErrorMessage":"CouponCode is invalid",
            "ErrorCode":"InvalidCouponCode"
        },
        ...
    }
}
        
Coupon Codes are normalized to uppercase alphanumeric values before beeing validated. This means that a customer might enter 'ABc*12-3' which will be normalized to 'ABC123'. The same is done with the codes specified in the billwerk Admin UI. This means a specified code 'AB-C1-23' will match the customer's code 'ABc*12-3'.

Synchronization

Your system needs to be kept in sync with all changes processed via customer self service.

To keep your system synchronized please pay attention to the following advices:

  • Never rely on the customer's workflow will ever reach the last step, e.g. the customer might have closed the browser before success page was loaded, or the final response might have been lost in the vasts of internet. You need to face this by consuming our Webhooks and trigger subsequent processes on your side.
  • Do not presume your customer will finish a process, e.g. do not create a customer in your database before you got notified by billwerk with the AccountCreated webhook showing the signup was finished successfully.

Stand-Alone Examples

The documentation is still a bit rough cut. The following working examples will help you get you started. To use the samples with your own account, replace all account specific ids like publicApiKey, planVariantId, and componentId.

Going Live

From the technical point of view you need to make sure to load BillwerkJS from the Live Instance of billwerk

<script type="text/javascript" src="https://app.billwerk.com/selfService/billwerkJS"></script>
Get your publicApiKey from the live settings and update your code accordingly.
paymentService = new BillwerkJS.Payment({ publicApiKey : "527cc4c951f45b08c493d834" }...
Also update your plan variant ids and component ids.

When done with the technical todos make sure the PSP settings on the Live System are ready to do real payments. Make at least one real life test for each supported payment method.

BillwerkJS Methods

BillwerkJS.Payment

BillwerkJS.Payment(paymentConfig, ready, error) Constructor. Creates an instance of BillwerkJS.Payment, loads the configured payment methods for your billwerk account from our server, loads required PSP-specific libraries and initializes them. Because of the external calls required, this can take a while and should only be performed once on a page.

The operation can't complete before the DOMContentLoaded event is fired, but you can call this method before the DOM is ready to parallelize requests.
paymentConfig Type: paymentConfig Your paymentConfig. This basically contains your public BillwerkJS API key and optional redirect URLs for PSPs that require redirection, as well as two js callbacks that can be used to customize the appearance of the 3ds checks for paymill. In the paymill documentation, these are called tdsInit and tdsCleanup.

BillwerkJS.Signup

The method subscribe is a wrapper of the methods createOrder and paySignupInteractive. For an initial signup subscribe will usually be the method you want to call. If you already created an order via REST API, e.g. for subsequent subscriptions of an existing user, you need to call paySignupInteractive directly.
BillwerkJS.Signup() Constructor. Creates an instance of BillwerkJS.Signup.
preview(cart, customerData, success, error) Previews what an order for this cart and customerData would look like and what the total amount will be. This is useful if you want to implement a 'dynamic pricing table' where the customer can edit the quantity and will see an updated version of the invoice immediately.

Only the first preview() call will perform an HTTP request immediately, subsequent calls will have a 700ms delay so you don't need to worry about hitting the rate limit too soon.
cart Type: cart A description of the products in this order.
customerData Type: customerData Information about the customer such as name, address, VAT ID, etc. This information is required already because the final price might depend on the country of residence, VAT ID, etc.
subscribe(billwerkJSPayment, cart, customer, secretPaymentData, success, error) Creates an order and initiates the payment in a single step. This is a mere wrapper for createOrder and paySignupInteractive.
When paying with a white-label PSP calling this method is a one-step stateless operation. Calling it several times will process several orders, e.g. the customer double clicks the order button. Prevent this in your signup implementation.
billwerkJSPayment Type: BillwerkJS.Payment An instance of BillwerkJS.Payment.
cart Type: cart A description of the products in this order.
customer Type: customerData Information about the customer such as name, address, VAT ID, etc. This information is required already because the final price might depend on the country of residence, VAT ID, etc.
secretPaymentData Type: secretPaymentData The potentially secret payment information entered by the customer to pay for the order.
createOrder(cart, customerData, success, error) Creates an order object on the server. The order object can later be paid for. This is useful to show the definite amount to the user before proceeding to checkout or if you need to validate orders manually.
cart Type: cart A description of the products in this order.
customerData Type: customerData Information about the customer such as name, address, VAT ID, etc. This information is required already because the final price might depend on the country of residence, VAT ID, etc.
{
  "firstName": "Marcellus",
  "lastName": "Wallace",
  "emailAddress": "mw@example.com"
  "vatId" : "DE123465789"
}
paySignupInteractive(billwerkJSPayment, secretPaymentData, order, success, error) Initiates interactive payment of the given order.
billwerkJSPayment Type: BillwerkJS.Payment An instance of BillwerkJS.Payment.
secretPaymentData Type: secretPaymentData The potentially secret payment information entered by the customer to pay for the order.
order Type: order An order object previously created either via BillwerkJS.Signup.createOrder() or via a backend call or via the billwerk user interface. Must look like { OrderId : "(id)", GrossTotal : 23.4, Currency : "EUR" }

BillwerkJS.Portal

BillwerkJS.Portal(customerToken) Constructor. Creates an instance of BillwerkJS.Portal.
customerToken Type: string A token to identify and authenticate a customer. You can request this token from the API via GET /contracts/:contractId/selfServiceToken.
upgradePaySync(orderId, success, error) Allows the customer to pay for an upgrade using the currently active payment method in a 'synchronous' fashion, i.e. the success method will be called only after the call to the PSP has finished. This method is non-interactive, the user can't change the active payment method using this call. Also note that this does not require to load client-side payment libraries.
orderId Type: string Id of an order to pay for. The order must have been created before using a backend API call.
upgradePayInteractive(billwerkJSPayment, secretPaymentData, order, success, error) Allows the customer to pay for an upgrade using new payment data. This method is interactive. Forward user to PSP page if URL is returned. See 'Integrating Black Label Providers'.
billwerkJSPayment Type: BillwerkJS.Payment An instance of BillwerkJS.Payment.
secretPaymentData Type: secretPaymentData The potentially secret payment information entered by the customer to pay for the order.
order Type: order An order object previously created either via BillwerkJS.Signup.createOrder() or via a backend call or via the billwerk user interface. Must look like { OrderId : "(id)", GrossTotal : 23.4, Currency : "EUR" }
invoicePdfDownloadUrl(invoice) Creates a download url for a PDF document. The URL will point to billwerk, so using this method makes billwerk 'visible' to your customers. If you want to avoid this, you will have to route requests through your server or mirror the PDFs proactively. To get a list of invoices for a contract please use the function contractDetails(...).
invoice Type: string or an invoice object Either the id of the invoice or an invoice object that has an 'Id' field.
a url string to download the PDF, including the customerToken that is required for authentication.
contractDetails(success, error) Returns details about the current contract, customer, and payment method. It also lists recent invoices.
contractCancel(success, error) Cancels the contract regularly, so that it ends at the next possible point in time given by the cancellation period and minimum contract duration settings.
customerChange(customerData, success, error) Changes a customer's data such as name, address or VAT id.

It will be possible to prohibit this method call under Settings -> BillwerkJS in case you don't want users to be able to change their data without prior verification, or if you want to allow data changes only in your system.
Caution! Changing customer data affects all contracts of the customer.
customerData Type: customerData An object containing the new customer data. If a field in this object is unset, it will be unset in the customer, too, so this has PUT semantics, not PATCH semantics.

paymentChange(billwerkJSPayment, secretPaymentData, success, error) Sets up a new payment method for the contract.
billwerkJSPayment Type: BillwerkJS.Payment An instance of BillwerkJS.Payment that will be used to talk to the payment service provider. At present, the instance must be ready before calling this method.
secretPaymentData Type: secretPaymentData Potentially secret payment data required for the respective payment method, e.g. credit card or direct debit information.

BillwerkJS.finalize

BillwerkJS.finalize(success, error) For interactive PSPs like PayPal this needs to be executed on the return page the PSP redirects to after finishing a payment. It triggers finalizing the order in billwerk. The success and error callback can be used to inform the customer if the order succeeded ot not.

Please note that you must never rely on the finalize page is ever called during the order process, e.g. a customer could close the browser after successful payment or something else happens. Always use our webhooks to be notified a subscription was successful.

BillwerkJS Types

paymentConfig A configuration object that must be passed to BillwerkJS.Payment upon initialization.
publicApiKey Type: string A public key used to identify your account. You can see your key under Settings -> BillwerkJS.
providerReturnUrl Type: string A url that will be used to redirect users back to your site when using a payment provider that requires redirects, such as PayPal. The page at this url must invoke the BillwerkJS.finalize() method.

This parameter is required when using PSPs that rely on redirects (e.g. PayPal, Skrill, PayOne with 3D-Secure).
popupCreate Type: function(redirect, cancelCallback) Optional. A function that will be called when a popup must be created. Currently, this is only used for showing 3D-Secure iframes when using paymill. The method signature is the same as in paymill's JS bridge where it's called tdsInit.
popupClose Type: function() Optional. A function called by BillwerkJS to destroy the popup created using popupCreate. In the paymill documentation, that is called tdsCleanup.

Example

var paymentConfig = {
    // REQUIRED. Your BillwerkJS public API key
    "publicApiKey": "527cc4c951f45909c493c820",
    // OPTIONAL. for Paymill and PayOne, REQUIRED for PSPs like PayPal, Skrill:
    "providerReturnUrl": "http://yourdomain.com/signup/finalize.html",
    // OPTIONAL. Overwrite the handling of the 3d-secure iframes when using paymill.
    "popupCreate": function(redirect, cancelCallback) { ... }
    "popupClose": function() { ... }
};
            
cart
planVariantId Type: objectid The id of the plan variant to subscribe to
componentSubscriptions Type: array of component order Optional. An array of additional components to subscribe to. Please note that id must be billwerk' id of the component (i.e. you can't use your own id here) and that the component must not be a metered component.
Heads Up! We'll add support for your own component ids in a future release.
couponCode Type: string Optional. Pass a coupon code entered by a customer to take into account the corresponding discount.

Example

var cart = {
    planVariantId : "527caacdeb596a247c6e0500",
    componentSubscriptions : [ {
        // required
        componentId : "5277ba54eb596a0ee85199c6",
        // required, can have decimals
        quantity : 23
    }, ... ],
    couponCode : "ABC-DEF"
};
secretPaymentData An object that contains payment information such as credit card data or bank accounts.
bearer Type: string A string that indicates which payment provider and payment bearer medium to use. Populate this from the list of available payment providers (refer to the Angular example), or simply hardcode it.

Example

// Credit Card payments
var paymentInfo = {
    "bearer": "CreditCard:Paymill",
    "cardNumber": "5169147129584558",
    "expiryMonth": "12",
    "expiryYear": "2015",
    "cardHolder": "Marcellus Wallace",
    "cvc": "123"
};
// Direct debit payments
var paymentInfo = {
    "bearer": "Debit:Paymill",
    "accountHolder": "Marcellus Wallace",
    "bankAccountNumber": "1234567890",
    "bankRoutingCode": "70050010"
}
var paymentInfo = {
    "bearer": "Debit:Paymill",
    "accountHolder": "Marcellus Wallace",
    "iban": "DE13501105170648485890",
    "bic": "INGDDEFFXXX"
}
// Black Label payment providers
var paymentInfo = { "bearer": "PayPal", "emailAddress" : "paypal_acct@example.com" };
var paymentInfo = { "bearer": "Skrill" };
var paymentInfo = { "bearer": "FakePSP" }; //For testing only
        

The bearer can be one of the following values:

"CreditCard:Paymill", 
"CreditCard:PayOne", 
"CreditCard:Wirecard",
"CreditCard:Stripe",
"CreditCard:Heidelpay",
"CreditCard:FakePSP", 
"Debit:Paymill", 
"Debit:PayOne",
"Debit:Wirecard",
"Debit:Heidelpay",
"Debit:SlimPay",
"Debit:Stripe",
"Debit:FakePSP", 
"OnAccount:PayOne",
"PayPal", 
"FakePSP",
"InvoicePayment",
"None:None"
"None:None" can be used for freemium signups (requires the correspondig plan to have the 'allow signup without payment information' flag set).

For PayPal the email address has to be passed at this point. It can't be modified during PayPal checkout process. If not passed, billwerk uses the email address of the customer data.
Important! It is required to integrate credit card payments in a PCI compliant way. Unless you are PCI-DSS certified do not send any credit card data to your server. BillwerkJS will return a tetheredPaymentInformation object which contains PSP-specific information such as a payment token which will subsequently be sent to Billwerk.
customerData An object that contains information about a customer.
If you need to identify the customer with your own id during signup please use the field tag at this point to pass the foreign Id to billwerk. The customer object also has an externalCustomerId field, which is unique in billwerk. Do not use externalCustomerId during initial signup. Instead read the tag upon signup notification via webhook and set the externalCustomerId by updating the customer object with the REST API.
    {
        emailAddress : "john.doe@example.com",
        firstName : "John",
        lastName : "Doe"
        tag : "A53FD212-7879-44AD-923C-56DD20012100",
        companyName : "ACME, Inc."
        vatId : "DE123465789",
        phoneNumber : "0123-45678",
        address : { 
                "addressLine1": "c/o Coworking Ltd.",
			    "street": "Torstraße"
			    "houseNumber": "89a",
			    "postalCode": "10123",
			    "city": "Berlin",
			    "country": "DE" },
        locale : "en-US"
    }
Custom Fields This data type also supports custom fields. To use custom fields in BillwerkJS at all access rights need to be defined from within the billwerk Admin UI on a per-field-base. Because not all custom fields are necessarily accessible via BillwerkJS the PATCH sematic is different to the one in the REST API. Custom fields not specified in BillwerkJS will not be removed in the resource. If you want to explicitely remove a custom field pass null. For further detail please also take a look here.
{
    customFields :
    {
        myCustomFieldKey1 : "MyCustomFieldValue1" ,
        myCustomFieldKey2 : null //Will be removed
        //If MyCustomFieldKey3 exists it will not be removed
    }
}
{
    customFields.myCustomFieldKey1 : "MyCustomFieldValue1",
    customFields.myCustomFieldKey2 : null //Will be removed
}

BillwerkJS Callbacks

error(errorData) Most BillwerkJS methods provide a callback to handle errors.
errorCode is an array that provides a hierarchy of error codes. At least one value is provided. This can be used to implement error specific behaviour of your page, e.g. inform the customer some credit card data was incorrect and let him correct it.
Possible values created by BillwerkJS:
IteroServerError,
PspServerError,
Timeout,
InvalidKey,
InvalidConfiguration,
InvalidPaymentData,
InvalidData,
UnmappedError,
Aborted,
AcquirerServerError,
AuthorizationRejected,
RateLimit,
InvalidTransaction,
AmountLimitExceeeded,
InvalidPaymentMethod,
InvalidCardType,
InvalidCardNumber,
InvalidExpirationDate,
InvalidCardCvc,
InvalidCardHolder,
3DsProblem,
InvalidAmount,
InvalidCurrency,
InvalidAccountNumber,
InvalidAccountHolder,
InvalidBankCode,
InvalidIban,
InvalidBic,
InvalidCountry,
BearerRejected,
BearerExpired,
InvalidCouponCode
Possible values returned by the server on failed payments:
LimitExceeded,
BearerInvalid,
BearerExpired,
InvalidCountry,
InvalidAmount,
InvalidCurrency,
LoginError,
InvalidData,
InsufficientBalance,
AlreadyExecuted,
InvalidPreconditions,
InternalError,
InternalProviderError,
RateLimit,
InvalidConfiguration,
PermissionDenied,
Canceled,
Rejected,
UnmappedError //for PSP errors not mapped to a specific billwerk code
errorMessage is an error message for your internal use. It is NOT prepared for direct notification of the customer.
referenceIdReserved for future use.
referenceUrlReserved for future use.
detailsReserved for future use.
{
    errorCode : ["InvalidCardCvc"],
    errorMessage : "",
    referenceId: "",
    referenceUrl: "",
    details: ""
}
Please check the structure of the passed object before using it. Currently, the passed object might have a different structure under certain circumstances.