Connect a provider
A connection is one credential, one provider, one environment, one merchant account. This flow is what happens between pasting and ACTIVE, and what to do for each provider.
Click any step to read what happens there and what can refuse it.
Stripe
- In the Stripe Dashboard, switch to Test mode. Developers → API keys → Create restricted key.
- Grant Write on PaymentIntents, Charges, Refunds and Webhook Endpoints. Everything else can stay None.
- Copy the
rk_test_…key. In Pehmen: Connections → Stripe → name it → paste → Validate and connect. - The connection record shows the
we_…webhook endpoint Stripe returned and the URL it delivers to. Nothing else to do.
If you did not grant Webhook Endpoints: Write, the connection is stored DEGRADED with WEBHOOK_REGISTRATION_SCOPE_MISSING. It still routes. To fix it either recreate the key with the permission and call POST /v1/connections/{id}/validate, or create the endpoint yourself in Stripe at the URL on the record and paste its signing secret:
curl -X POST "$API/v1/connections/$CONNECTION/webhook-secret" \
-H "x-api-key: $KEY" -H "x-pehmen-organization: $ORG" -H "x-pehmen-environment: test" \
-H "idempotency-key: $(uuidgen)" -H "content-type: application/json" \
-d '{"kind":"STRIPE_ENDPOINT","secret":"whsec_..."}'
HitPay
- In the HitPay sandbox dashboard, copy the API key.
- Pehmen: Connections → HitPay → name it → paste → Validate and connect. The connection is stored with webhook setup required and shows the URL to give HitPay:
…/webhooks/hitpay/{connection}. - In HitPay, create a webhook endpoint at that URL. Paste the two salts through the API, one call each:
HITPAY_ENDPOINT_SALTfor v2 event webhooks (the per-endpoint salt the dashboard shows when you create the endpoint).HITPAY_ACCOUNT_SALTfor v1 payment-request callbacks (the account salt).
Until the salts are pasted, the platform will not hear about outcomes it did not ask for, and payments will resolve through the query loop instead.
Airwallex
- In the Airwallex sandbox dashboard, create an API key. Note the client id and the API key.
- Pehmen: Connections → Airwallex → name it → Client ID → paste the key → Validate and connect. Flow type is
PAYOUT: this connection sends money; it never takes payments. - In Airwallex, create a webhook at
…/webhooks/airwallex/{connection}and paste the secret with kindAIRWALLEX_ENDPOINT.
A live Airwallex connection is refused outright in this release: live third-party access uses a registered OAuth application, not sandbox keys.
Afterwards
- Rotate a credential with
POST /v1/connections/{id}/rotate. The old one keeps verifying for 24 hours, so nothing in flight breaks. - Revoke with
POST /v1/connections/{id}/revoke, or delete the key at the provider. Either alone is sufficient because you own the account. - Re-validate a
DEGRADEDconnection withPOST /v1/connections/{id}/validate; the check runs on the worker and the result lands on the record.
Signatures on inbound provider webhooks are verified on the raw body with a constant-time comparison against the active secret, then the retiring one. Signatures are never logged.