Kill Bill payment plugin that uses OMPay as the payment gateway.
Configure the plugin with your OMPay merchant details and API credentials. The available properties are:
org.killbill.billing.plugin.ompay.merchantId: Your OMPay Merchant ID.org.killbill.billing.plugin.ompay.clientId: Your OMPay API Client ID.org.killbill.billing.plugin.ompay.clientSecret: Your OMPay API Client Secret.org.killbill.billing.plugin.ompay.testMode: Set totruefor sandbox/testing,falsefor live. Defaults totrue.org.killbill.billing.plugin.ompay.apiBaseUrl: (Optional) Override the default OMPay API base URL. Defaults arehttps://api.sandbox.ompay.com/v1/merchantsfor test mode andhttps://api.ompay.com/v1/merchantsfor live mode.org.killbill.billing.plugin.ompay.killbillBaseUrl: (Optional) The base URL of your Kill Bill instance, used for constructing redirect URLs. Defaults tohttp://127.0.0.1:8080.
Upload the configuration to Kill Bill for your tenant:
curl -v \
-X POST \
-u admin:password \
-H 'X-Killbill-ApiKey: bob' \
-H 'X-Killbill-ApiSecret: lazar' \
-H 'X-Killbill-CreatedBy: admin' \
-H 'Content-Type: text/plain' \
-d 'org.killbill.billing.plugin.ompay.merchantId=YOUR_OMPAY_MERCHANT_ID
org.killbill.billing.plugin.ompay.clientId=YOUR_OMPAY_CLIENT_ID
org.killbill.billing.plugin.ompay.clientSecret=YOUR_OMPAY_CLIENT_SECRET
org.killbill.billing.plugin.ompay.testMode=true # Optional
# org.killbill.billing.plugin.ompay.killbillBaseUrl=http://<your_killbill_host>:8080 # Optional
# org.killbill.billing.plugin.ompay.apiBaseUrl=[https://custom.api.ompay.com/v1/merchants](https://custom.api.ompay.com/v1/merchants) # Optional' \
[http://127.0.0.1:8080/1.0/kb/tenants/uploadPluginConfig/killbill-ompay](http://127.0.0.1:8080/1.0/kb/tenants/uploadPluginConfig/killbill-ompay)This outlines the typical flow for adding a payment method using OMPay, potentially involving 3DS.
-
Create a Kill Bill account for the customer: (Standard Kill Bill API - same as your Gocardless example) This will return the Kill Bill
accountId.curl -v \ -X POST \ -u admin:password \ -H 'X-Killbill-ApiKey: bob' \ -H 'X-Killbill-ApiSecret: lazar' \ -H 'X-Killbill-CreatedBy: tutorial' \ -H 'Content-Type: application/json' \ -d '{ "currency": "OMR" }' \ '[http://127.0.0.1:8080/1.0/kb/accounts](http://127.0.0.1:8080/1.0/kb/accounts)'Note the
accountIdfrom theLocationheader in the response. -
Get Payment Form Descriptor from OMPay Plugin: Your application backend calls the plugin's
/formendpoint to get details needed to render the OMPay payment form.curl -v \ -X GET \ -u admin:password \ -H "X-Killbill-ApiKey: bob" \ -H "X-Killbill-ApiSecret: lazar" \ -H 'X-Killbill-CreatedBy: tutorial' \ '[http://127.0.0.1:8080/plugins/killbill-ompay/form?kbAccountId=](http://127.0.0.1:8080/plugins/killbill-ompay/form?kbAccountId=)<ACCOUNT_ID>&returnUrl=[https://yourshop.com/payment/ompay_return&cancelUrl=https://yourshop.com/payment/ompay_cancel&paymentIntent=auth¤cy=OMR&amount=0.100](https://yourshop.com/payment/ompay_return&cancelUrl=https://yourshop.com/payment/ompay_cancel&paymentIntent=auth¤cy=OMR&amount=0.100)'- Replace
<ACCOUNT_ID>with the customer's Kill Bill account ID. returnUrl: URL where OMPay redirects after successful 3DS or payment attempt.cancelUrl: URL where OMPay redirects if the user cancels.paymentIntent:authfor authorization,salefor purchase.currency&amount: Specify for the transaction (e.g., a small auth amount).
The response will be a JSON similar to this:
{ "kbAccountId": "<ACCOUNT_ID>", "formMethod": "POST", "formUrl": "[http://127.0.0.1:8080/plugins/killbill-ompay/process-nonce](http://127.0.0.1:8080/plugins/killbill-ompay/process-nonce)", "formFields": [ {"key": "amount", "value": "0.100", "isHidden": false}, {"key": "currency", "value": "OMR", "isHidden": false} ], "properties": [ {"key": "ompayClientToken", "value": "your_ompay_client_access_token", "isHidden": false}, {"key": "isSandbox", "value": "true", "isHidden": false} ] }Key fields:
formUrl: The endpoint where the payment nonce will be submitted.properties.ompayClientToken: The client token from OMPay to initialize their SDK/form.
- Replace
-
Render OMPay Form and Submit Nonce:
- On your frontend, use the
ompayClientTokento initialize the OMPay payment form (e.g., using OMPay's JavaScript SDK). - When the user submits their card details, the OMPay SDK will provide a payment
nonce. - Your application backend then POSTs this
nonceand other details to theformUrlobtained in Step 2 (which is/plugins/killbill-ompay/process-nonce).
curl -v \ -X POST \ -u admin:password \ -H "X-Killbill-ApiKey: bob" \ -H "X-Killbill-ApiSecret: lazar" \ -H 'X-Killbill-CreatedBy: tutorial' \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "nonce=<GENERATED_OMPAY_NONCE>&kbAccountId=<ACCOUNT_ID>&amount=0.100¤cy=OMR&paymentIntent=auth&returnUrl=[https://yourshop.com/payment/ompay_return&cancelUrl=https://yourshop.com/payment/ompay_cancel&force3ds=false](https://yourshop.com/payment/ompay_return&cancelUrl=https://yourshop.com/payment/ompay_cancel&force3ds=false)" \ '[http://127.0.0.1:8080/plugins/killbill-ompay/process-nonce](http://127.0.0.1:8080/plugins/killbill-ompay/process-nonce)'The response from
/process-noncewill be JSON. Example:{ "success": true, "kb_payment_id": "...", "kb_transaction_id": "...", "transaction_type": "AUTHORIZE", "status": "PENDING", // or PROCESSED, ERROR "ompay_transaction_id": "ompay_txn_...", "requires_3ds": true, // if true, a redirect_url will be present "redirect_url": "https://ompay_3ds_url/..." // if requires_3ds is true } - On your frontend, use the
-
Handle 3DS Redirect (if applicable):
- If the response from Step 3 indicates
requires_3ds: trueand provides aredirect_url, your application must redirect the user's browser to this OMPay URL. - After the user completes the 3DS authentication, OMPay will redirect them back to the
returnUrlyou initially provided. This callback to yourreturnUrlshould include asessionIdfrom OMPay (e.g., as a query parameter?sessionId=ompay_session_xyz).
- If the response from Step 3 indicates
-
Add Payment Method to Kill Bill (Complete 3DS Flow or if no 3DS):
-
If 3DS occurred: Extract the
sessionIdfrom the OMPay redirect (Step 4). -
Call Kill Bill's standard endpoint to add a payment method. Pass the
sessionIdas a plugin property. This tells the OMPay plugin to finalize the payment method addition using the session data from OMPay.curl -v \ -X POST \ -u admin:password \ -H 'X-Killbill-ApiKey: bob' \ -H 'X-Killbill-ApiSecret: lazar' \ -H 'X-Killbill-CreatedBy: tutorial' \ -H 'Content-Type: application/json' \ -d '{ "pluginName": "killbill-ompay", "pluginInfo": { "properties": [ { "key": "sessionId", "value": "<SESSION_ID_FROM_OMPAY_REDIRECT>" } // You might also include other properties if needed by your frontend/backend logic ] } }' \ '[http://127.0.0.1:8080/1.0/kb/accounts/](http://127.0.0.1:8080/1.0/kb/accounts/)<ACCOUNT_ID>/paymentMethods?isDefault=true' -
If no 3DS was required (Step 3 resulted in
status: "PROCESSED"andrequires_3ds: false): The payment method might have been added automatically during the/process-noncecall if the transaction was successful and yielded a card token. You can verify by listing payment methods for the account. If it wasn't automatically added, or if you prefer explicit control, you could potentially call the same endpoint as above but without thesessionIdand instead providing OMPay card/payer tokens if available and if the plugin supports direct token-based PM creation (checkOmPayPaymentPluginApi#addPaymentMethodDirectlogic). However, the primary flow described involves the nonce and optional session.
This call (with
sessionId) returns the Kill BillpaymentMethodIdin theLocationheader. -
-
Trigger Payments against the new Payment Method: (Standard Kill Bill API - same as your Gocardless example, using the
paymentMethodIdfrom Step 5)curl -v \ -X POST \ -u admin:password \ -H "X-Killbill-ApiKey: bob" \ -H "X-Killbill-ApiSecret: lazar" \ -H "X-Killbill-CreatedBy: tutorial" \ -H "Content-Type: application/json" \ --data-binary '{"transactionType":"PURCHASE","amount":"10.000", "currency": "OMR", "paymentMethodId": "<PAYMENT_METHOD_ID>"}' \ '[http://127.0.0.1:8080/1.0/kb/accounts/](http://127.0.0.1:8080/1.0/kb/accounts/)<ACCOUNT_ID>/payments'Note the
paymentIdfrom theLocationheader. -
Obtain Information about the Payment: (Standard Kill Bill API - same as your Gocardless example)
curl -v \ -u admin:password \ -H "X-Killbill-ApiKey: bob" \ -H "X-Killbill-ApiSecret: lazar" \ '[http://127.0.0.1:8080/1.0/kb/payments/](http://127.0.0.1:8080/1.0/kb/payments/)<PAYMENT_ID>?withPluginInfo=true' -
Webhook Handling: Configure OMPay to send webhooks to
/plugins/killbill-ompay/webhook. The plugin will process these notifications to update transaction statuses in Kill Bill.
This flow should align with how your OmPayPaymentPluginApi.java, OmPayFormServlet.java, and OmPayNonceHandlerServlet.java are structured and how your C# BillingService interacts with them.