Configuration
A client is built once from six values and reused for the life of the process. It is safe to share between threads or requests.
Required values
| Value | Where it comes from | Notes |
|---|---|---|
| Base URL | https://panama.deepayment.com/api/v1 | Scheme and host only, https required. A path, query or fragment is rejected; the SDK appends /api/v1/... itself. |
| Access Key | Merchant portal | Public identifier. Sent in Merchant-Access-Key; the platform uses it to find your registered public key. |
| Merchant private key | Generated by you | Ed25519, base64. Both the 32-byte seed that libsodium and OpenSSL produce and the 64-byte seed-plus-public-key form are accepted. Never leaves your servers. See Key setup. |
| Platform body key id | Merchant portal | Names the platform X25519 key that seals your POST bodies. It travels in the envelope so the gateway knows which private key opens it. |
| Platform body public key | Merchant portal | X25519, base64, 32 bytes. Must be the key named by the body key id. |
| Platform webhook public keys | Merchant portal | Map of keyId to Ed25519 public key, base64, 32 bytes each. Required even if you do not consume webhooks. |
Keys are environment specific. Do not reuse production keys in a test environment.
Webhook key rotation
The webhook carries the keyid it was signed with, and the SDK looks that id up in the map you configured. During a rotation the platform announces the new key before signing with it; add it to the map so both keys are present, and remove the old one after the platform stops using it. A webhook signed with a key that is not in the map fails verification.
Building the client
- Go
- JavaScript
- Python
- PHP
- Java
import deepayment "github.com/deepayment/sdk-go"
c, err := deepayment.NewClient(deepayment.Config{
BaseURL: "https://panama.deepayment.com",
AccessKey: "mak_live_xxx",
MerchantPrivateKeyBase64: merchantPrivateKey,
PlatformBodyKeyID: "body_20260827_01",
PlatformBodyPublicKeyBase64: platformBodyPublicKey,
PlatformWebhookPublicKeys: map[string]string{
"pwhk_20260827_01": platformWebhookPublicKey,
},
// optional
Timeout: 30 * time.Second, // ignored when HTTPClient is set
HTTPClient: nil, // your own *http.Client, e.g. with a proxy
UserAgent: "", // default merchant-sdk-go
AcceptLanguage: "", // default en-US; message language of error text
MaxResponseBytes: 0, // default 8 MiB
})
NewClient returns an error, not a client, when a value is missing or malformed. The error names the field.
import { Client } from '@support-deepayment/sdk';
const client = new Client({
baseUrl: 'https://panama.deepayment.com',
accessKey: 'mak_live_xxx',
merchantPrivateKeyBase64: merchantPrivateKey,
platformBodyKeyId: 'body_20260827_01',
platformBodyPublicKeyBase64: platformBodyPublicKey,
platformWebhookPublicKeys: { pwhk_20260827_01: platformWebhookPublicKey },
// optional
timeoutMs: 30000,
userAgent: 'merchant-sdk-js',
acceptLanguage: 'en-US',
maxResponseBytes: 8 * 1024 * 1024,
fetchImpl: globalThis.fetch, // inject your own fetch, e.g. with a proxy agent
});
The constructor throws ConfigError when a value is missing or malformed.
from deepayment import Client
client = Client(
base_url="https://panama.deepayment.com",
access_key="mak_live_xxx",
merchant_private_key_base64=merchant_private_key,
platform_body_key_id="body_20260827_01",
platform_body_public_key_base64=platform_body_public_key,
platform_webhook_public_keys={"pwhk_20260827_01": platform_webhook_public_key},
# optional
timeout=30.0,
user_agent="merchant-sdk-python",
accept_language="en-US",
max_response_bytes=8 * 1024 * 1024,
)
All arguments are keyword-only. The constructor raises ConfigError when a value is missing or malformed.
use Deepayment\Sdk\Client;
$client = new Client([
'baseUrl' => 'https://panama.deepayment.com',
'accessKey' => 'mak_live_xxx',
'merchantPrivateKeyBase64' => $merchantPrivateKey,
'platformBodyKeyId' => 'body_20260827_01',
'platformBodyPublicKeyBase64' => $platformBodyPublicKey,
'platformWebhookPublicKeys' => ['pwhk_20260827_01' => $platformWebhookPublicKey],
// optional
'timeout' => 30, // seconds
'userAgent' => 'merchant-sdk-php',
'acceptLanguage' => 'en-US',
'maxResponseBytes' => 8 * 1024 * 1024,
'transport' => null, // callable(url, method, headers, body): [status, rawBody]
]);
The constructor throws ConfigException when a value is missing or malformed.
import com.deepayment.sdk.Client;
import java.time.Duration;
import java.util.Map;
Client client = Client.builder()
.baseUrl("https://panama.deepayment.com")
.accessKey("mak_live_xxx")
.merchantPrivateKeyBase64(merchantPrivateKey)
.platformBodyKeyId("body_20260827_01")
.platformBodyPublicKeyBase64(platformBodyPublicKey)
.platformWebhookPublicKeys(Map.of("pwhk_20260827_01", platformWebhookPublicKey))
// optional
.timeout(Duration.ofSeconds(30))
.userAgent("merchant-sdk-java")
.acceptLanguage("en-US")
.maxResponseBytes(8 * 1024 * 1024)
.transport(null) // Client.Transport for a custom HTTP stack
.build();
build() throws DeepaymentException.Config when a value is missing or malformed. Requests and responses are Map<String, Object> whose keys match the API Reference.
Optional settings
| Setting | Default | Effect |
|---|---|---|
| Timeout | 30 s | Whole request, connect to last byte. On timeout the SDK returns a transport error; the outcome is unknown, see Errors. |
| User-Agent | merchant-sdk-<lang> | Sent on every request. Append your own product name if you want to identify your integration in platform logs. |
| Accept-Language | en-US | Language of the human-readable message in error responses. |
| Max response bytes | 8 MiB | A larger response is discarded and reported as a response-too-large error. |
| HTTP client / transport / fetch | built in | Inject your own when you need a proxy, custom TLS or connection pooling. Go ignores Timeout when HTTPClient is set; configure the timeout on your client instead. |
Clock
Signatures carry created and expires timestamps at most 300 seconds apart and the platform rejects signatures outside the window. Keep the server clock synchronized with NTP; a drift of more than a few minutes makes every request fail with UNAUTHORIZED.