Take the payment in a form on your own website. BillPro finishes it and sends the customer back to you.
| Time | Status | User Agent | |
|---|---|---|---|
Retrieving recent requests… | |||
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'sintegrityattribute.checkout.form_action: the form'saction. 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 orderpending.checkout.resultsays why and the other checkout fields arenull. 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>- Set
wpwlOptionsbefore the script loads. It configures the form. - Load
paymentWidgets.jsfrom the gateway:https://eu-test.oppwa.comfor testing,https://eu-prod.oppwa.comwhen you go live. - Add a
formwith the classpaymentWidgets. Setactiontocheckout.form_action, anddata-brandsto 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.
| Card | Number | Result |
|---|---|---|
| Visa | 4200000000000091 | Success, no 3-D Secure challenge |
| Visa | 4200000000000042 | Success after a 3-D Secure challenge |
| Mastercard | 5200000000000007 | Success, no 3-D Secure challenge |
| Mastercard | 5200000000000015 | Success after a 3-D Secure challenge |
Customise the form
Set these in wpwlOptions:
style:card,plainornone. Useplainornoneto apply your own styles.locale: the form's language, such asenorde.brandDetection:truedetects the card brand from the number.onReady: runs when the form has loaded.onError: runs on an error.InvalidCheckoutIdErrormeans the checkout expired: create a new one.onBeforeSubmitCard: runs before the card is sent. Returnfalseto 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 tofalseto 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-tx01order_id: the order.status:success,failedorpending.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 stayspending: 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,pendingorrejectedorder with no successful payment. It renews the same order: no new order is created. - A
failedorder can't be renewed (422, codeorder_already_activated). Charge a saved card instead with Charge a stored card. - The body is optional. Send
redirect_success_urlorredirect_failed_urlonly to change them. - Renewing doesn't change the order's status, and sends no webhook. Always use the newest checkout.