SDKs
Server-side SDKs for the Inovio gateway in PHP, Node, Python and Java, covering the v1 card surface against API v4.14.
Four server-side libraries wrap the Inovio Gateway Payments Service so you call
client.sale() instead of assembling REQUEST_ACTION=CCAUTHCAP form fields by
hand. They are language-idiomatic projections of one object model: a partner
reading the Node docs recognises the PHP shape one for one.
All four target API version 4.14 and cover the v1 card surface: sale,
authorize, capture, line-item capture, reverse, reverse capture, refund, force
credit, status, order update, tokenize, and the two health checks. Payment
methods are Card, Token and SavedCard. ACH, EU direct debit, LatAm
vouchers, wallets, subscriptions and disputes are modelled in the type system
but not implemented, so adding them later fills existing seams rather than
breaking your integration.
Version 0.1.0-alpha, and not published to any package registry. Install from the public GitHub repository, as shown below. Pin a commit until a tagged release lands.
What the SDKs are for
Every one of them is a server-side library. They hold your gateway credentials, sign token-service requests with your site key, and speak the gateway's form-encoded protocol. None of them runs in a browser.
What you get over raw HTTP:
- Actions become methods.
client.refund(orderRef, amount), not aREQUEST_ACTIONstring plus six correlated parameters. - The five-state result.
APPROVED,DECLINED,PENDING,RUNNING,FAILED, with noapprovedboolean to makePENDINGlook like a failure. - Decimal money. Amounts never pass through a binary float in any of the four languages.
- Typed references.
capture()takes anOrderRef, so it cannot be handed a customer id by mistake. - Idempotency and timeout recovery. Setting an order id makes a retry return the original result instead of charging twice, and the timeout exception carries the key you need to reconcile.
- Wire quirks normalised once. The
REQUEST_INITATORmisspelling, theXTL_ORDER_IDandXTL_PO_IDduality,PMT_L4versusPMT_LAST4, and the case-inconsistent response keys never reach you.
See How the SDKs think for the object model these share.
Choosing a language
| PHP | Node / TypeScript | Python | Java | |
|---|---|---|---|---|
| Minimum runtime | PHP 8.0 | Node 18 | Python 3.8 | Java 11 |
| Extra dependencies | none (Composer) | none | none | none |
| Required extensions | ext-json, ext-bcmath, ext-curl |
n/a | n/a | n/a |
| HTTP client | cURL, injectable | fetch, injectable |
urllib, injectable |
java.net.http, injectable |
| Amount type | bcmath decimal string | decimal string | decimal.Decimal |
BigDecimal |
| Concurrency | synchronous | promise-based | synchronous | synchronous |
| Package name | inovio/gateway-sdk |
@inovio/gateway-sdk |
inovio-gateway-sdk |
com.inoviopay:inovio-gateway-sdk |
| Version | 0.1.0-alpha | 0.1.0-alpha | 0.1.0-alpha | 0.1.0-alpha |
| Registry status | not on Packagist | not on npm | not on PyPI | not on Maven Central |
| 3D Secure | full server legs | BrowserData only |
BrowserData only |
BrowserData only |
| Repository | inovio-gateway-sdk-php | inovio-gateway-sdk-node | inovio-gateway-sdk-python | inovio-gateway-sdk-java |
| Page | PHP | Node | Python | Java |
The 3D Secure row is the one real capability difference. PHP ships the full
server-leg client (prepare(), the enrollment leg, completeSale()); the other
three carry the BrowserData block and read the challenge nextAction from a
result, but do not yet expose a threeDSecure() sub-client. If you need gateway
3DS today, use PHP or drive the 3DS endpoints directly.
Node is the reference implementation. It defined the canonical method surface and the conformance fixtures the other three run against, so where the four disagree, Node is the intended shape.
Install and first transaction
Each SDK installs from its public GitHub repository. Below is the install command followed by a sale, in each language.
The gateway endpoint defaults to the sandbox
(https://api-uap.inoviopay.com/payment/pmt_service.cfm). Pass the
PRODUCTION environment to switch to https://api.inoviopay.com/payment/pmt_service.cfm,
or override the endpoint outright to point at a local stack or a proxy.
# composer.json: add the repository, then require the package
composer config repositories.inovio vcs https://github.com/Inoviopay/inovio-gateway-sdk-php
composer require inovio/gateway-sdk:dev-main
use Inovio\Gateway\{Credentials, InovioClient};
use Inovio\Gateway\Model\{LineItem, Money, PaymentMethods};
use Inovio\Gateway\Request\TransactionRequest;
$client = new InovioClient(new Credentials($user, $password, '123'), 'SANDBOX');
$req = (new TransactionRequest(
PaymentMethods::card('4111111111111111', '122030', '123'),
[new LineItem('SKU-1', 1, Money::of('10.00', 'USD'))]
))->withIdempotency('ORDER-555'); // retry-safe by default
$result = $client->sale($req);
match ($result->status) {
'APPROVED' => /* fulfil */,
'DECLINED' => /* $result->outcome->service, $result->serviceClassification */,
'PENDING' => /* $result->nextAction — 3DS challenge, redirect, voucher */,
default => /* RUNNING | FAILED */,
};
npm install github:Inoviopay/inovio-gateway-sdk-node
import { InovioClient, Money, PaymentMethods, Refs } from '@inovio/gateway-sdk';
const client = new InovioClient(
{ reqUsername: process.env.INOVIO_USER!, reqPassword: process.env.INOVIO_PASS!, siteId: '123' },
{ environment: 'SANDBOX' }
);
const result = await client.sale({
paymentMethod: PaymentMethods.card('4111111111111111', '122030', '123'),
lineItems: [{ productId: 'SKU-1', count: 1, value: Money.of('10.00', 'USD') }],
idempotency: { xtlOrderId: 'ORDER-555' }, // retry-safe by default
});
switch (result.status) {
case 'APPROVED': /* fulfil */ break;
case 'DECLINED': /* result.outcome.service, result.serviceClassification */ break;
case 'PENDING': /* result.nextAction — 3DS challenge, redirect, voucher */ break;
case 'RUNNING':
case 'FAILED': break;
}
pip install "git+https://github.com/Inoviopay/inovio-gateway-sdk-python.git@main"
from inovio_gateway import (
Credentials, InovioClient, Money, PaymentMethods, TransactionStatus,
)
from inovio_gateway.model import Idempotency, LineItem
from inovio_gateway.request import TransactionRequest
client = InovioClient(Credentials(user, password, site_id="123"), environment="SANDBOX")
result = client.sale(TransactionRequest(
payment_method=PaymentMethods.card("4111111111111111", "122030", "123"),
line_items=[LineItem("SKU-1", 1, Money.of("10.00", "USD"))],
idempotency=Idempotency(xtl_order_id="ORDER-555"), # retry-safe by default
))
if result.status is TransactionStatus.APPROVED:
...
elif result.status is TransactionStatus.PENDING:
result.next_action # 3DS challenge, redirect, voucher
git clone https://github.com/Inoviopay/inovio-gateway-sdk-java.git
cd inovio-gateway-sdk-java && mvn install
# then depend on com.inoviopay:inovio-gateway-sdk:0.1.0-alpha.0
InovioClient client = new InovioClient(
new InovioClient.Credentials(user, password, "123"));
TransactionRequest req = new TransactionRequest(
PaymentMethods.card("4111111111111111", "122030", "123"),
new LineItem("SKU-1", 1, Money.of("10.00", "USD")))
.idempotency("ORDER-555"); // retry-safe by default
TransactionResult r = client.sale(req);
switch (r.status()) {
case APPROVED: /* fulfil */ break;
case DECLINED: /* r.outcome().service(), r.serviceClassification() */ break;
case PENDING: /* r.nextAction() — 3DS challenge, redirect, voucher */ break;
case RUNNING:
case FAILED: break;
}
Where the card number goes
Every SDK's tokenize() is a server-side call. It POSTs the PAN to
token_service.cfm from your process, which means the card number transits
your infrastructure and your server sits inside your own cardholder data flow.
That is a deliberate property of this surface, not an oversight.
The lower-scope alternative is a browser client that tokenizes the PAN without it ever reaching your server. That Hosted Fields client is not yet available. Until it ships, your options are:
- Server-side
tokenize(), accepting that the PAN passes through your server. See Tokenization for the endpoint contract. - Browser direct-post to
token_service.cfm. The token service sendsAccess-Control-Allow-Origin: *, so a browser can post the PAN to it directly once your server has supplied an HMAC signature. This is what the cart plugins do: the shopper's browser exchanges the PAN for aTOKEN_GUID, and only the token reaches the store's PHP. All four SDKs export the signing helper that a merchant-hosted signature endpoint needs.
The site key that signs a token request is a per-site HMAC secret issued by Inovio support. It is not your gateway password, and it must never be shipped to a browser.
What is next
- How the SDKs think walks the shared object model: the status lifecycle, decimal money, idempotency, outcome tiers, order-level reconciliation, tokenization and 3D Secure.
- The per-language pages give the full method surface, the language-specific ergonomics, and the runnable examples in each repository.
- Shopping carts covers the pre-built store plugins, which are a different integration path from calling an SDK yourself.