Get Started
Integration prerequisites
Before integrating, make sure you have:
partner_id(for example:ECHEZONA001)- one or more valid
client_idvalues for merchants under the partner - shared API security values:
x-api-key- HMAC shared secret (for
x-clive-hmac)
- Stripe account and PaymentIntent integration on your side
- public HTTPS webhook URL to receive signed Clive status callbacks
Integration options
You can integrate in either mode:
- Raw API mode: call Clive endpoints directly and compute
x-clive-hmacyourself. - SDK mode: install
@clive-alliance/partner-sdkso request signing, auth headers, and idempotency defaults are handled for you.
See: NPM SDK Integration
Fastest path (same pattern as sandbox-web)
If you want the easiest production-safe flow, copy this pattern:
- Your backend calls Clive initialize
- Your backend creates Stripe PaymentIntent
- Your backend calls Clive attach-intent
- Your frontend renders Stripe Payment Element and confirms payment
Stripe ownership boundary (important)
In the production partner flow, you create and own the Stripe PaymentIntent.
Clive does not create it for you on /transactions/initialize and /transactions/attach-intent.
That means your backend is responsible for:
- setting
statement_descriptor_suffix - setting Stripe metadata for internal tracing
- persisting Stripe identifiers alongside Clive identifiers
Required records to persist on your side
For every checkout attempt, store:
clive_tx_idstripe_payment_intent_idstatement_descriptor_suffix- your immutable business reference (
echezona_reference) - idempotency key used for initialize/attach
Backend endpoint example
// POST /checkout-intent
const initialized = await clive.initializeTransaction({
partner_id: "ECHEZONA001",
client_id: "AIRPEACE001",
amount: 750,
currency: "USD",
echezona_reference: `EZ-${Date.now()}`
});
const paymentIntent = await stripe.paymentIntents.create({
amount: 75000, // cents
currency: "usd",
statement_descriptor_suffix: "AIRPEACE",
automatic_payment_methods: { enabled: true },
receipt_email: "buyer@example.com",
metadata: {
clive_tx_id: initialized.clive_tx_id,
partner_id: "ECHEZONA001",
client_id: "AIRPEACE001",
echezona_reference: "EZ-12345"
}
});
await clive.attachPaymentIntent({
clive_tx_id: initialized.clive_tx_id,
stripe_payment_intent_id: paymentIntent.id
});
return {
clive_tx_id: initialized.clive_tx_id,
client_secret: paymentIntent.client_secret
};
Frontend example (Stripe Elements)
const { error } = await stripe.confirmPayment({
elements,
confirmParams: { return_url: window.location.href },
redirect: "if_required"
});
if (!error) {
// refresh tx status from your backend/Clive read endpoint
}
Environment variables (partner side)
CLIVE_API_BASE_URL=https://<your-host>/api/v1
CLIVE_API_KEY=<your-partner-api-key>
CLIVE_HMAC_SECRET=<shared-hmac-secret>
Required headers by endpoint type
| Endpoint type | Required headers |
|---|---|
| Partner transaction ingestion | x-api-key, x-clive-hmac, idempotency-key |
| Partner read endpoints | x-api-key |
| Admin endpoints | Authorization: Bearer <jwt> |
| Stripe webhook to Clive | stripe-signature |
Generate HMAC signature
x-clive-hmac is the SHA-256 HMAC of the exact raw request body.
node -e "const c=require('crypto');const body='{\"partner_id\":\"ECHEZONA001\",\"client_id\":\"AIRPEACE001\",\"amount\":750,\"currency\":\"USD\",\"echezona_reference\":\"EZ12345\"}';console.log(c.createHmac('sha256', process.env.CLIVE_HMAC_SECRET).update(body).digest('hex'))"
Idempotency expectations
- Use a unique
idempotency-keyper logical create/attach action. - If you retry with the same key, Clive returns the original payload with
idempotentReplay: true. - Keep keys stable across network retries from your app or gateway.
First successful flow checklist
- Call
POST /transactions/initialize - Create Stripe PaymentIntent in your backend (including
statement_descriptor_suffix) - Call
POST /transactions/attach-intent - Complete payment UI using Stripe Payment Element
- Consume Clive webhook updates on your webhook URL
Next: USD Integration Flow