Host a checkout on your website

Take the payment in a form on your own website. BillPro finishes it and sends the customer back to you.

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…

Take the payment in a form on your own website. You create the order with a checkout, show the gateway's payment form, and BillPro finishes the payment and sends the customer back to you with the result.

You can run every step on this page against the sandbox API and the gateway's test environment, so no money is taken.

1. Create the order with a checkout

Send Create order from your server with create_checkout: true and your two return URLs.

curl -X POST "https://test-api.bill.pro/api/v2/profiles/{profile_id}/orders" \
  -H "Authorization: Bearer $BILLPRO_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "order": {
      "order_type": "single_payment",
      "currency": "EUR",
      "customer_id": 4471,
      "order_products_attributes": [{ "product_id": 433, "qty": 1 }],
      "create_checkout": true,
      "redirect_success_url": "https://your-website.example/payment-result",
      "redirect_failed_url": "https://your-website.example/payment-result"
    }
  }'
  • redirect_success_url: where the customer goes after an approved payment, or when the outcome couldn't be confirmed.
  • redirect_failed_url: where the customer goes after a declined payment. It can be the same URL.

The order is created as pending, and the response adds checkout. Keep these fields:

  • checkout.id: loads the payment form.
  • checkout.integrity: the script tag's integrity attribute.
  • checkout.form_action: the form's action. It's BillPro's page, not yours.

Good to know:

  • The customer pays the order's first payment, as on a payment link: the whole amount for a single payment or metered order, the first payment for a subscription, and the deposit (or first instalment) for an instalment order.
  • If the gateway fails, you still get 201, with the order pending. checkout.result says why and the other checkout fields are null. Renew the checkout.

Try it: the request on this page is Create order, with the Single payment with a custom checkout example selected. Enter your API token and profile_id, set customer_id and product_id to a customer and product on your sandbox profile, and select Try It. On this page, both return URLs are replaced with this page's address, so you come back here after paying. The payment form in step 2 loads from the response.

2. Show the payment form

Load the gateway's script with the checkout, and point the form at checkout.form_action.

<script>
  var wpwlOptions = { style: "plain", locale: "en", brandDetection: true };
</script>

<script
  src="https://eu-test.oppwa.com/v1/paymentWidgets.js?checkoutId={checkout.id}"
  integrity="{checkout.integrity}"
  crossorigin="anonymous"></script>

<form
  action="{checkout.form_action}"
  class="paymentWidgets"
  data-brands="VISA MASTER"></form>
  1. Set wpwlOptions before the script loads. It configures the form.
  2. Load paymentWidgets.js from the gateway: https://eu-test.oppwa.com for testing, https://eu-prod.oppwa.com when you go live.
  3. Add a form with the class paymentWidgets. Set action to checkout.form_action, and data-brands to the card brands you accept.

The customer enters their card and presses Pay Now. If 3-D Secure applies, the gateway shows the bank's check first. BillPro then records the payment and sends the customer to your return URL.

Payment Details

Create the order with Try It. The payment form appears here.

Test cards

Use any expiry date in the future and any CVV. Never enter a real card.

CardNumberResult
Visa4200000000000091Success, no 3-D Secure challenge
Visa4200000000000042Success after a 3-D Secure challenge
Mastercard5200000000000007Success, no 3-D Secure challenge
Mastercard5200000000000015Success after a 3-D Secure challenge

Customise the form

Set these in wpwlOptions:

  • style: card, plain or none. Use plain or none to apply your own styles.
  • locale: the form's language, such as en or de.
  • brandDetection: true detects the card brand from the number.
  • onReady: runs when the form has loaded.
  • onError: runs on an error. InvalidCheckoutIdError means the checkout expired: create a new one.
  • onBeforeSubmitCard: runs before the card is sent. Return false to stop it.
  • iframeStyles: styles for the text inside the card number and CVV fields.
  • showOneClickWidget: if the customer saved a card on an earlier order, the form opens on that card, with its own Pay Now button and a Show other payment methods button for a new card. BillPro adds the customer's saved cards to the checkout for you. Set it to false to show only the new card form, for example when every payment must use a new card. The test form on this page does.

The card number and CVV fields are gateway iframes, so your CSS can't reach inside them: use iframeStyles. They only accept web-safe fonts, given as one unquoted name such as Verdana. Style everything else with your own CSS, using the form's wpwl- classes, such as .wpwl-button-pay.

To show the form again, for example with a new checkout, call wpwl.unload(), remove the form, add a new form and load the script again. See the gateway's widget guide for every option.

3. Handle the result

BillPro sends the customer to your return URL, with four query parameters added after your own:

https://your-website.example/payment-result?order_id=3990&status=success&result_code=000.100.110&checkout_id=0Example000CheckoutId000000000000.uat01-vm-tx01
  • order_id: the order.
  • status: success, failed or pending.
  • result_code: the gateway's result code, or one of BillPro's own codes below.
  • checkout_id: the checkout the customer paid through.

What each status means:

  • success (success URL): the payment was approved.
  • failed (failed URL): the card was declined, or the return couldn't be matched to the order (missing_result, result_mismatch). The order stays pending: renew the checkout to try again.
  • pending (success URL): the gateway hasn't confirmed the payment yet, the order is cancelled (order_unavailable), or BillPro couldn't confirm the outcome (status_unavailable, processing_error).

Don't fulfil the order from the redirect alone. Check the order's status with Show order, or listen for webhooks. Refreshing the return page never records the payment twice.

Payment result

After you pay in step 2, BillPro sends you back here with the result.


  

Return URL for this page:

4. Renew the checkout

A checkout expires 30 minutes after it's created, or as soon as the customer pays with it. Until then, you can load the payment form with it as often as you need. Renew it with Renew a custom checkout when it's more than 30 minutes old, or when the customer needs another try after a decline.

  • It works on a draft, pending or rejected order with no successful payment. It renews the same order: no new order is created.
  • A failed order can't be renewed (422, code order_already_activated). Charge a saved card instead with Charge a stored card.
  • The body is optional. Send redirect_success_url or redirect_failed_url only to change them.
  • Renewing doesn't change the order's status, and sends no webhook. Always use the newest checkout.
Path Params
integer
required
≥ 1

Your merchant profile ID. Required in every request.

Find it in the BillPro dashboard address, after /profiles/. For example, in /profiles/1234/orders the profile ID is 1234.

Body Params
order
object
required
Responses

Language
Credentials
Bearer
API token
URL
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json