A payment gateway is a way for a client to pay an invoice. CoreInto comes with two kinds: manual methods, where the client pays outside the site by following your instructions and staff record the payment, and online providers (PayPal, Stripe, JazzCash and Easypaisa), where the client is sent to the provider and the invoice is marked paid when the provider confirms the money. Gateways are set up under Settings > Payment Gateways. Every answer a provider sends is written to Billing > Gateway Log. Cards can be kept for automatic payments, refunds can be sent back through the provider, and clients whose card is about to expire are told. This chapter covers all of that. Recording a payment by hand, credit and the rest of invoicing are in Billing.
Settings > Payment Gateways
The page has two parts.
Set up lists the gateways you have. Each row shows the name clients see, its kind, its state and arrows to change the order. The order is the order clients see at checkout and on invoices. States:
| Badge | Meaning |
|---|---|
| On | Turned on. Clients can pay with it (unless it is staff only). |
| Off | Saved but not offered. Nothing can be paid with it. |
| Staff only | On, but not offered to clients. Only staff can choose it for an invoice or a client. |
| Sandbox | The gateway is in test mode and talks to the provider's test system. |
Add a gateway lists every kind this version has. A manual method asks for the name clients will see (for example "Bank Transfer" or "JazzCash / UBL Omni") and an Add button; you can add as many manual methods as you like. An online provider has one Set up button, and once it is set up the button becomes Change: only one of each online provider can exist. The page says that more gateways follow in a later update.
A new gateway starts turned off. After adding one you land on its settings page with the message "Fill in the details and turn it on."
Staff need the permission "Payment gateways" (settings.gateways) for this page.
The settings page of a gateway
Every gateway has these settings, above its own fields:
| Setting | What it does |
|---|---|
| Name clients see | The label at checkout, on invoices and in emails ("Paid with Bank Transfer"). Up to 100 characters. |
| Charge in this currency | "The invoice's currency", or one of your currencies. With a currency chosen, the amount is converted at your exchange rates before it is sent to the provider, and a payment the provider reports is converted back into the invoice's currency when it is recorded. Providers that take only some currencies show which ones. |
| Turned on | Whether the gateway can be used at all. |
| Offer it to clients (when ordering and on invoices); otherwise only staff can choose it | Off makes the gateway staff only. Staff can still set it as a client's payment method or an invoice's payment method, and that client then sees it on that invoice. |
Secret fields (passwords, keys, salts) are stored encrypted and never shown back. A saved secret shows the placeholder "Saved; type to replace" and a Remove button; leaving the box empty keeps the saved value.
A gateway that needs keys cannot be turned on while a required field is empty; the page says which one to fill in. Fields marked optional, and the Easypaisa merchant account number, API user name and API password, are not required to turn the gateway on. A gateway with a fixed list of currencies cannot be turned on with a "Charge in this currency" choice it does not take.
Online gateways also show two read-only addresses, the Notification address and the Return address. See "Addresses the provider needs" below.
Remove Gateway opens a pop-up that says what still uses the gateway: unpaid invoices that have it as their payment method, clients that have it as their default, cards kept with it, and past payments. It offers the other enabled gateways as a replacement; choosing one moves the unpaid invoices and the clients' default to it, the kept cards of the removed gateway are deleted (the client pays by another method next time), and past payments keep the gateway's name as text so the history stays readable. The counts are written to the activity log.
Manual payment (bank transfer, mobile wallet, cash)
The kind is listed as "Manual payment (bank transfer, mobile wallet, cash...)". The client pays outside the site; you record the payment when it arrives (on the invoice page, see Billing).
| Field | What it does |
|---|---|
| Instructions for the client | Account details and what to write as the reference. {invoice_number} and {amount} are replaced with the invoice number and the amount owed in the gateway's currency. The invoice number is always shown with the instructions. |
Use one manual gateway per way of paying: "Bank Transfer" with your account details, "Cheque by post" with your postal address, "Cash at our office", "JazzCash / UBL Omni" with the wallet number, and so on. Each has its own name and instructions.
What the client sees: on an unpaid invoice, the instructions are shown under the payment box with the line "Please mention invoice #NUMBER with your payment." When several gateways are offered and a manual one is selected, the button reads "Show how to pay" and shows that gateway's instructions. Nothing is marked paid until staff record the payment.
The address of a manual gateway (used inside CoreInto, for example in the gateway log) is made from its name: "Bank Transfer" becomes banktransfer.
PayPal
| Field | What it does |
|---|---|
| Client ID | From an app made under developer.paypal.com. |
| Secret | The app's secret. |
| Webhook ID (optional) | The ID of a webhook you add at PayPal for the event PAYMENT.CAPTURE.COMPLETED, pointing to the notification address. With it set, PayPal's notifications are checked with PayPal and recorded; without it, notifications are ignored and only the client's return records the payment. |
| Sandbox (test payments) | Talks to PayPal's sandbox. |
How it works: CoreInto creates a PayPal order for the amount owed and sends the client to PayPal to approve it (PayPal account or a card on PayPal). When the client comes back, the payment is captured and recorded. A payment PayPal holds for review is recorded as pending; the client is told PayPal is holding it. PayPal's fee is recorded with the payment when it is reported in the same currency.
PayPal takes these currencies: AUD, BRL, CAD, CNY, CZK, DKK, EUR, HKD, HUF, ILS, JPY, MYR, MXN, TWD, NZD, NOK, PHP, PLN, GBP, SGD, SEK, CHF, THB and USD. An invoice in another currency must be converted with "Charge in this currency"; otherwise the client is told PayPal does not take that currency and to choose another way to pay.
Refunds can be sent back through PayPal.
Stripe (cards, Apple Pay, Google Pay)
| Field | What it does |
|---|---|
| Secret key | From dashboard.stripe.com. A test key starts with sk_test_. |
| Webhook signing secret | From a webhook endpoint you add at Stripe for the events checkout.session.completed and checkout.session.async_payment_succeeded, pointing to the notification address. Every notification's signature is checked with it; a notification that does not match is refused. Optional: without it, the client's return records the payment. |
| Offer to keep the card for automatic payments | On by default. Shows the client a "Keep my card for automatic payments" box when paying. |
How it works: CoreInto opens a Stripe Checkout session for the amount owed and sends the client to Stripe's page. The return and the webhook both confirm the payment; it is recorded once. A session that completed but whose payment is still being processed is recorded as pending. Stripe's fee is recorded with the payment.
Stripe takes any currency Stripe supports; CoreInto handles the currencies Stripe counts without decimals.
Kept cards: when the client ticks the box, Stripe keeps the card against a customer record and CoreInto keeps only a sealed reference, the brand, the last four digits and the expiry month. Card numbers never reach CoreInto. Kept cards are charged without the client being present (see "Saved cards and automatic capture"). Refunds can be sent back through Stripe.
JazzCash
| Field | What it does |
|---|---|
| Merchant ID | From the JazzCash merchant portal (sandbox.jazzcash.com.pk for tests). |
| Password | The merchant password. |
| Integrity salt | Used to sign every request and check every answer. |
| Way to pay | "The client chooses on JazzCash", "JazzCash wallet", "Card" or "Voucher paid at a shop". |
| Sandbox (test payments) | Talks to the JazzCash sandbox. |
How it works: the client is shown a short page "Taking you to JazzCash" that sends a signed form to JazzCash's hosted checkout (page redirection, version 1.1). JazzCash posts the signed result back to the return address. CoreInto checks the signature before it records anything. Response code 000 is paid. Codes 124 and 157 mean the client has a voucher to pay at a shop; the payment is recorded as pending and the client is told to pay the voucher. Anything else fails with JazzCash's message.
JazzCash takes Pakistani rupees only. Amounts are sent in paisa. Refunds and kept payment methods are not available through JazzCash.
Easypaisa
| Field | What it does |
|---|---|
| Store ID | From your Easypay merchant account. |
| Hash key | Signs the request sent to Easypay. |
| Merchant account number | Used when checking a payment with Easypay. |
| API user name | Used to check each payment with Easypay before the invoice is marked paid. |
| API password | Its password. |
| Way to pay | "Easypaisa account", "Card", "At a shop (voucher)" or "QR code". |
| Sandbox (test payments) | Talks to Easypay's staging system. |
How it works: the client is sent to Easypay with a signed request. Easypay sends the client back to the token address with a token, which CoreInto confirms on Easypay (the client passes through another short "Taking you to Easypaisa" page), and the client returns once more. Before the invoice is marked paid, CoreInto asks Easypay's transaction inquiry what happened to the order, so nothing the browser carries is trusted. Paid, pending (Easypay has not received the money yet) and failed follow from that answer.
If the API user name is empty, CoreInto cannot ask Easypay, so the payment is recorded as pending with the message "Easypaisa will confirm the payment; staff will mark the invoice paid." Fill in the API user name and password to have invoices marked paid automatically.
Easypaisa takes Pakistani rupees only. Refunds and kept payment methods are not available through Easypaisa.
Addresses the provider needs
Each online gateway's settings page shows two addresses. They have no session; they act only on what the provider confirms, then send the client to the invoice.
| Address | Used for |
|---|---|
/gateway/NAME/notify | The notification address (webhook, IPN). PayPal and Stripe send their events here. Answers OK, invalid (a signature that does not check) or try again (a temporary error, status 503). |
/gateway/NAME/return/INVOICE | Where the client comes back to after paying. Given to the provider with each payment; you do not configure it at the provider. |
/gateway/NAME/token/INVOICE | A step in the middle of a payment; only Easypaisa uses it. |
NAME is the gateway's address name (paypal, stripe, jazzcash, easypaisa). The page shows the addresses in the form your installation uses (short addresses or index.php?r=..., see "Address style" under General Settings), so copy them from there.
What to configure at the provider:
- PayPal: a webhook for PAYMENT.CAPTURE.COMPLETED pointing to the notification address; paste its ID into "Webhook ID".
- Stripe: a webhook endpoint for
checkout.session.completedandcheckout.session.async_payment_succeededpointing to the notification address; paste its signing secret into "Webhook signing secret". - JazzCash and Easypaisa: nothing; the return and token addresses are sent with each payment.
What the client sees
At checkout, the offered gateways are shown as a list of choices; the client's own default payment method (set on the client's profile by staff) is selected first. The setting "After checkout" (General Settings, Ordering) has a choice "Go straight to payment": with it, a new order with an online gateway sends the client to the provider at once; with a manual gateway the invoice is opened instead.
On an unpaid invoice (/client/invoices/ID), the Balance box shows:
- "Pay with" and a list of gateways when more than one is offered and the setting "Clients may change the payment method of an invoice" (ClientsChooseGateway) is on. With it off, the invoice's payment method is fixed and shown as text, unless that method is no longer offered.
- "Keep my card for automatic payments" when the selected gateway can keep cards (Stripe with the option on).
- "Pay now", or "Show how to pay" for a manual method.
- The instructions of the selected manual method.
- One button per kept payment method, "Pay with Visa •••• 4242", which charges that method at once.
When a payment cannot be started (the provider refuses the keys, is unreachable, or does not take the currency), the client is sent back to the invoice with a message and the attempt is written to the gateway log as "Could not start".
After coming back from the provider the invoice page shows one of these messages (the address carries ?payment=...):
| Code | Message |
|---|---|
| paid | Thank you, your payment was received. |
| pending | Your payment is being processed. The invoice will be marked paid when the provider confirms it. |
| failed | The payment was not completed. You can try again or choose another way to pay. |
| cancelled | You cancelled the payment. You can try again whenever you like. |
| error | We received your payment but could not record it automatically; our staff will sort it out. |
Mass pay: with "Clients may pay several invoices at once" (MassPay) on, the client ticks two or more unpaid invoices on My Invoices and CoreInto makes one invoice whose lines are the others; paying it marks them all paid. Invoices for adding funds cannot be included.
Billing > Payment Methods (/client/payment-methods) lists the client's kept cards with brand, last digits, expiry (marked expired when past), the gateway, "Make default" and "Remove". Removing a card deletes the reference; the row stays for the record. The page says card numbers are never stored by CoreInto.
How a provider's answer becomes a payment
Whatever route the answer arrives by (return, token step, notification, or a charge of a kept card), the same steps run:
- The answer is written to the gateway log with its result.
- A payment with the same gateway and provider transaction ID is recorded once, however often the provider repeats itself.
- If the invoice cannot be found, or the money is in a currency CoreInto does not use, nothing is recorded; the log entry says "Unknown invoice" or "Unknown currency" and the client is told staff will sort it out.
- Money paid in another currency is converted into the invoice's currency at your exchange rates, fees included.
- Money for a cancelled or draft invoice is recorded as a transaction and added to the client's credit, with the message "The invoice had been cancelled, so your payment was added to your account credit."
- Otherwise the payment is added to the invoice, which is marked paid when the balance is covered, and everything a paid invoice sets off runs (services set up, suspensions lifted, domains registered, commissions; see Billing). The invoice's payment method is set to this gateway if it was another.
- The payment confirmation email goes to the client and the "Payment received" notice to staff.
- A card the provider returned for keeping is saved as the client's payment method; the first one becomes the default.
Saved cards and automatic capture
Only Stripe can keep cards in this version. A kept card is charged in three ways:
- By the client, with the "Pay with ..." button on an invoice.
- By staff, on the admin invoice page: "Kept payment method" with a list of the client's cards and "Charge now" (permission "Edit invoices and add payments"). Staff need this when a client asks for a charge over the phone.
- By the daily task capture-payments, which charges due invoices.
The task works like this. Every day it looks at unpaid invoices (and invoices in collections) due within "Charge saved payment methods this many days before the due date" days, for clients who have a kept payment method, are not closed, and do not have "Do not charge saved payment methods automatically" ticked on their profile. Each invoice is tried once when it comes into range, then again once a week for "Try again every week for (weeks)" weeks, unless "Try only once" is ticked. The default payment method is charged, for what is still owed on the invoice. A failed charge sends the client the email "Automatic payment failed" (payment_failed) with the reason.
| Setting (Settings > Automation Settings, tab Payment capture) | What it does |
|---|---|
| Charge saved payment methods this many days before the due date | 0 charges on the due date; up to 60. |
| Try only once | After the first try, never try that invoice again automatically. |
| Try again every week for (weeks) | 0 to 52 weekly retries after the first try. |
| Day of the month for card expiry notices | 1 to 28; see below. |
Client flag: on the client's profile, "Do not charge saved payment methods automatically" (auto_capture_off) excludes that client from the task. The client can still pay with the card by hand, and staff can still press "Charge now".
A kept card whose gateway has been turned off is skipped with "The payment method's gateway is not active."
Card expiry notices
The task card-expiry-notices runs daily. On or after the day set in "Day of the month for card expiry notices" (default 25), it emails every client whose kept card expires in the current month the template "Saved card about to expire" (card_expiring) with the card type, last four digits and expiry month, asking them to add a new payment method. Each card is told once. The client's Payment Methods page marks expired cards.
Refunds through the gateway
On the admin invoice page, each payment has a Refund section (permission "Refund payments", invoices.refund) with the amount and where the money goes:
- "Send it back through PayPal" or "Send it back through Stripe": shown only when the payment was made through a gateway that can refund and carries a provider transaction ID. CoreInto asks the provider to refund the amount (converted to the gateway's charging currency when one is set), records the refund with the provider's reference, and writes "Refunded" to the gateway log. If the provider refuses, nothing is recorded and the reason is shown.
- "Record a refund I sent myself": for manual gateways, JazzCash and Easypaisa, and for any payment you returned another way.
- Refund to the client's credit.
Ticking "Email the client" sends "Refund issued" (refund_issued). Partial refunds are allowed; a payment can be refunded until the whole of it is gone. The rest of refunds and reversals are in Billing.
Billing > Gateway Log
Every answer from a payment provider is written here (permission "View the gateway log", gateway_log). Filters: gateway, result and invoice number. Each row shows the date, the gateway, the invoice (linked), the result and the first part of the details; the date opens the full entry with everything the provider sent, laid out as text. Passwords, secrets, card numbers, hashes and tokens the provider echoes back are replaced with "(hidden)" before they are stored.
| Result | Meaning |
|---|---|
| Successful | A payment the provider confirmed. |
| Pending | The provider has not confirmed the money yet (held for review, voucher not paid, processing). |
| Failed | The provider said the payment did not go through, or an answer did not check (bad signature). |
| Could not start | The payment could not be started at the provider (keys refused, unreachable). |
| Error | A provider call failed while handling a return or a notification. |
| Unknown invoice | Money arrived for an invoice CoreInto cannot find. |
| Unknown currency | Money arrived in a currency CoreInto does not have. |
| Not recorded | The payment could not be written to the invoice; the entry says why. |
| Refunded | A refund sent through the gateway. |
The activity log also records when a client starts paying an invoice and when staff add, change, turn on or off, or remove a gateway.
Staff-only gateways and payment methods per client
A client's profile has "Payment method" (default_gateway): the gateway chosen for that client's new invoices and selected first at checkout. A service and a domain also have a "Payment method" of their own; renewal invoices use it. Staff can choose a staff-only gateway in these places; the client then sees it on those invoices even though it is not offered to everyone.
Still to come and not yet tried
- More gateways follow in a later update (roadmap piece 8b): Authorize.net, 2Checkout, Skrill, WorldPay, Pay4bit, PayFast (Pakistan and South Africa), Perfect Money, and the crypto providers Binance Pay, BitPay, Cryptomus, Heleket and Plisio.
- Subscriptions (the provider charging on its own schedule) are not built; CoreInto charges kept cards itself with the capture-payments task.
- PayPal, Stripe, JazzCash and Easypaisa have not yet been tried against the providers' sandboxes; that needs the owner's test accounts. Turn on Sandbox, make a test payment and read the gateway log before taking real payments.
- Mass pay records one transaction on the mass-pay invoice; splitting it across the invoices it pays is still to come.
