@clive-alliance/partner-sdk
v0.1.9
Published
Official Clive Payments partner SDK with signed server APIs and browser checkout widget components.
Maintainers
Readme
@clive-alliance/partner-sdk
Official Clive Payments partner SDK for:
- Server-side signed API calls (Node.js/TypeScript)
- Browser checkout widget (Clive Pay Components v2)
Server SDK features
Use this SDK to handle request signing, auth headers, and idempotency for:
POST /transactions/initializePOST /transactions/attach-intentPOST /transactions/checkout-intentPOST /transactions/checkout-intent-v2
If you prefer calling APIs directly, you can still use helpers like createSignedRequestHeaders.
Install
npm install @clive-alliance/partner-sdkQuick start
import { CliveClient } from "@clive-alliance/partner-sdk";
const clive = new CliveClient({
baseUrl: "https://api.clivepayments.com/api/v1",
apiKey: process.env.CLIVE_API_KEY!,
hmacSecret: process.env.CLIVE_HMAC_SECRET!
});
const initialized = await clive.initializeTransaction({
partner_id: "ECHEZONA001",
client_id: "AIRPEACE001",
// Major currency units (e.g. 75.0 dollars), not Stripe minor units (cents).
amount: 75.0,
currency: "USD",
echezona_reference: "EZ12345"
});
// Partner creates Stripe PaymentIntent and then attaches it.
const attached = await clive.attachPaymentIntent({
clive_tx_id: initialized.clive_tx_id,
stripe_payment_intent_id: "pi_3Qxx..."
});
const routed = await clive.createCheckoutIntentV2({
partner_id: "ECHEZONA001",
client_id: "AIRPEACE001",
amount: 75,
currency: "GBP",
email: "[email protected]",
echezona_reference: "EZ12346",
payment_type: "card",
issuer_country: "GB"
});Useful helpers
CliveClient.createIdempotencyKey(prefix, reference)CliveClient.createRandomIdempotencyKey(prefix)CliveClient.signPayload(rawBody, hmacSecret)createSignedRequestHeaders(rawBody, apiKey, hmacSecret, idempotencyKey)
Error handling
SDK requests throw CliveApiError on non-2xx responses:
status- HTTP status codecode- Clive domain error code (if returned)details- extra validation/domain context
Clive Pay Components (Widget v2, advanced option)
Keep your current direct Stripe Elements flow if you prefer.
If you want a richer hosted-like experience, use createClivePaymentsWidget.
Widget v2 includes:
- Payment-method selection UI
- Searchable billing-country selection
checkout-intent-v2initialization- Built-in processor renderers:
- Stripe (
card) - Revolut card field (
cardrouted to revolut) - Revolut Pay (
revolut_pay) - Revolut Open Banking / Pay By Bank (
open_banking)
- Stripe (
- Built-in terminal outcome views (success/failure), plus external callbacks for host apps
Browser usage
import { createClivePaymentsWidget } from "@clive-alliance/partner-sdk";
const widget = createClivePaymentsWidget({
mount: "#clive-pay-container",
partnerId: "ECHEZONA001",
clientId: "AIRPEACE001",
brandingBaseUrl: "https://api.clivepayments.com/api/v1",
amount: 75,
currency: "GBP",
email: "[email protected]",
echezonaReference: "EZ12347",
initializeTransaction: async (payload) => {
// IMPORTANT: call your backend adapter endpoint here.
// Do not expose Clive API key + HMAC secret in browser code.
const response = await fetch("/api/clive/checkout-intent-v2", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
});
if (!response.ok) throw new Error("Failed to initialize checkout");
return await response.json();
},
onSuccess: ({ payload, response, result }) => {
// Notify your host app / analytics / order finalization flow.
console.log("Payment succeeded", { payload, response, result });
},
onError: (error) => {
// Notify your host app outside the widget.
console.error("Payment failed", error);
},
onStateChange: (state) => {
// Optional external state tracking.
console.log("Widget state:", state);
}
});
// Optional cleanup
// widget.destroy();Integration boundary (very important)
Use this split exactly:
- Widget -> Clive (direct):
GET /branding/packetonly (public branding payload)
- Widget -> Partner backend -> Clive:
POST /transactions/checkout-intent-v2(signed/authenticated server call)
The widget is intentionally designed to call your backend for transaction initialization through initializeTransaction.
Customer Browser (Widget)
-> POST /api/clive/checkout-intent-v2 (your backend)
-> POST /api/v1/transactions/checkout-intent-v2 (Clive, signed with x-clive-hmac)
<- processor checkout artifact (Stripe client_secret / Revolut order token)
<- return artifact JSON
-> widget mounts processor UI componentWhat must stay server-side
Never expose these in browser code:
CLIVE_API_KEYCLIVE_HMAC_SECRET- processor secret credentials (Stripe/Revolut/etc)
- request signing logic for Clive ingestion endpoints
Optional custom processor overrides
If you need fully custom processor rendering, you can still override defaults using renderers.
createClivePaymentsWidget({
// ...base options
renderers: {
revolut: async ({ root, response }) => {
root.innerHTML = `<p>Custom Revolut UI. Tx: ${response.clive_tx_id}</p>`;
}
}
});Security model
- Keep
apiKeyandhmacSecreton the server only. - Have browser widget call your backend adapter route.
- Backend adapter should call
CliveClient.createCheckoutIntentV2(...). - Widget can fetch
/branding/packet?client_id=...&partner_id=...automatically whenbrandingBaseUrlis provided.
