SDK y bibliotecas cliente
Las bibliotecas oficiales de SOAMTAR cubren los lenguajes de servidor, las apps móviles, el navegador, Unity y las principales plataformas de comercio electrónico. Todas están pensadas para Sierra Leona: importes en leones (SLE, también se aceptan USD y EUR), Orange Money Sierra Leone (orange_money_sl) como único proveedor, teléfonos del pagador en formato +232 seguido de 8 dígitos.
Disponibilidad
Las versiones siguientes son definitivas, pero los paquetes aún no están publicados en los registros públicos (npm, Packagist, PyPI, RubyGems, Maven Central, NuGet, pub.dev…). Mientras tanto, instálelos desde el repositorio fuente que le facilita el soporte de SOAMTAR. El SDK de navegador ya se sirve en https://app.so-amtar.com/sdk/soamtar.js (aún no está en npm).
¿Cómo elegir?
| Mi perfil | Mi recomendación |
|---|---|
| Estoy empezando | Siga la guía de inicio rápido. Es el camino más sencillo. |
| Uso un CMS | Vaya directamente a la sección Plugins CMS y comercio electrónico. |
| Soy desarrollador backend | Elija su lenguaje en la sección Servidor. |
| Creo una app móvil o un juego | Use las bibliotecas de la sección Móvil y frontend. Su backend sigue siendo quien crea el pago. |
Las páginas por lenguaje de servidor y la del navegador están disponibles en inglés.
Dos tipos de bibliotecas
| SDK de servidor | SDK cliente (navegador, móvil, Unity) | |
|---|---|---|
| Clave | Clave secreta sk_test_… / sk_live_… | Clave pública pk_test_… / pk_live_… (o ninguna) |
| Dónde se ejecuta | Solo en su backend | En el navegador, el teléfono o el juego del pagador |
| Qué hace | Crea pagos (POST /v1/payments), los consulta, verifica los webhooks | Abre la payment_url que su backend obtuvo con POST /v1/payments |
Un SDK cliente nunca crea un pago ni guarda una clave secreta. No existe un host sandbox separado: con una clave sk_test_, los pagos se simulan en https://app.so-amtar.com/v1.
Servidor (backend)
| Lenguaje | Paquete | Versión | Punto de entrada |
|---|---|---|---|
| PHP / Laravel | soamtar/soamtar-php (Composer, PHP 8.2+) | 1.1.0 | Soamtar\SoamtarClient, Soamtar\Soamtar |
| Node.js / TypeScript | @soamtar/sdk (npm) | 1.1.0 | SoamtarClient |
| Python | soamtar (pip) | 1.1.0 | soamtar.SoamtarClient |
| Ruby | soamtar (gem) | 1.1.0 | Soamtar::Client |
| Java | com.soamtar:soamtar-java (Maven) | 1.1.0 | com.soamtar.sdk.SoamtarClient |
| Go | github.com/soamtar/soamtar-go-sdk | 1.1.0 | soamtar.NewClient |
| .NET / C# | Soamtar (NuGet) | 1.1.0 | Soamtar.SoamtarClient |
Móvil y frontend
| Plataforma | Paquete | Versión | Punto de entrada |
|---|---|---|---|
| Navegador (JavaScript) | @soamtar/browser, o el script servido en https://app.so-amtar.com/sdk/soamtar.js | 1.0.0 | SoamtarSDK |
| iOS (Swift) | SoamtarSDK (Swift Package Manager, iOS 14+) | 1.0.1 | Soamtar, SoamtarCheckoutView |
| Android (Kotlin) | com.soamtar:soamtar-android (Gradle) | 1.1.0 | com.soamtar.sdk.Soamtar |
| Flutter | soamtar_sdk (pub) | 1.0.1 | package:soamtar_sdk/soamtar_sdk.dart |
| React Native | @soamtar/react-native (npm, con react-native-webview) | 1.1.0 | SoamtarClient, SoamtarCheckout |
| Unity (videojuegos) | Carpeta Assets/Soamtar | 1.0.1 | Soamtar.SoamtarClient |
Plugins CMS y comercio electrónico
| Plataforma | Plugin | Versión |
|---|---|---|
| WordPress / WooCommerce | SOAMTAR for WooCommerce (soamtar-gateway) | 1.1.0 |
| Magento 2 | soamtar/magento2-payment (módulo Soamtar_Payment) | 1.1.0 |
| PrestaShop 1.7.7+ | Módulo de pago soamtar | 1.1.0 |
| Drupal Commerce | soamtar/drupal-commerce (módulo soamtar_commerce) | 1.1.0 |
| Odoo | payment_soamtar (SOAMTAR Payment Provider) | 17.0.1.1.0 |
Terminales de pago (TPV / Smart POS)
Se está preparando un SDK de SOAMTAR para terminales de pago Android. Depende de endpoints /v1/pos/* que todavía no están disponibles en la API: no lo use en producción.
Convenciones comunes
Los SDK de servidor exponen la misma superficie, adaptada al estilo de nombres de cada lenguaje (CreateAsync en .NET, Create(ctx, …) en Go):
client.payments.create(params, idempotencyKey?) POST /v1/payments
client.payments.retrieve(id) GET /v1/payments/{id}
client.payments.list(filters) GET /v1/payments
client.payments.status(idOrReference) GET /v1/status/{idOrReference}
client.payments.verify(id) POST /v1/payments/{id}/verify
client.payouts.create / retrieve / list /v1/payouts
client.refunds.create / retrieve / list /v1/refunds
client.balance.retrieve() GET /v1/balance
client.webhooks.list / create / secret / sendTest /v1/webhooks
Webhook.constructEvent(rawBody, signatureHeader, secret)retrieveacepta el identificador o la referencia de SOAMTAR (TXN-…), no sumerchant_ref.- Los clientes de servidor rechazan cualquier clave que no empiece por
sk_. Si no se pasa ninguna clave, leenSOAMTAR_SECRET_KEY; la URL base viene deSOAMTAR_API_URL(SOAMTAR_BASE_URLsigue aceptándose como respaldo), por defectohttps://app.so-amtar.com/v1. - Cada
POSTlleva una cabeceraIdempotency-Key: generada automáticamente o la que usted pase. webhooks.create:subscribed_eventses opcional y por defecto valepayment.success,payment.failed,payout.success,payout.failed.webhooks.sendTest()(send_test/SendTestsegún el lenguaje) pide a SOAMTAR que envíe un eventowebhook.testa sus endpoints.- Los nombres antiguos (
webhooks.test,webhooks.all,balance.show,status.retrieve…) siguen disponibles como alias obsoletos. - Los errores lanzan una excepción de SOAMTAR con el estado HTTP y el código de error de la API.
La firma opcional de las peticiones (vea Authentication) es una opción del cliente:
| Lenguaje | Opción |
|---|---|
| Node.js | soamtar(key, { signRequests: true }) |
| PHP | 'sign_requests' => true |
| Python | SoamtarClient(..., sign_requests=True) |
| Ruby | Soamtar::Client.new(key, sign_requests: true) |
| Go | soamtar.WithSignRequests(true) |
| Java | new SoamtarClient(null, null, Duration.ofSeconds(30), true) (signRequests) |
| .NET | new SoamtarClient(signRequests: true) |
Función de verificación de webhooks por lenguaje:
| Lenguaje | Función |
|---|---|
| PHP | Soamtar\Webhook::constructEvent($rawBody, $signatureHeader, $secret) |
| Node.js | Webhook.constructEvent(rawBody, signatureHeader, secret) |
| Python | Webhook.construct_event(raw_body, signature_header, secret) |
| Ruby | Soamtar::Webhook.construct_event(raw_body, signature_header, secret) |
| Java | Webhook.constructEvent(payload, signatureHeader, secret) |
| Go | soamtar.ConstructEvent(payload, sigHeader, secret) |
| .NET | Webhook.ConstructEvent(payload, signatureHeader, secret) |
Cada función comprueba la cabecera X-Soamtar-Signature (t=<unix>,v1=<hmac>, más v2= durante la rotación de un secreto), recalcula HMAC-SHA256(secret, "t.payload") sobre el cuerpo sin procesar, rechaza marcas de tiempo de más de 300 segundos y devuelve el evento decodificado (event, created, data). Consulte Webhooks.
Reembolsos
client.refunds.create({ transaction_id, amount? }) devuelve el dinero al número Orange Money del pagador, con cargo a su saldo. Sin amount se reembolsa todo lo que queda; se permiten reembolsos parciales. El reembolso es asíncrono: el resultado llega con refund.success / refund.failed. La clave necesita el scope can_refund. Vea Refunds.
Patrones recomendados
Reutilizar el cliente
Cree un único cliente por proceso y reutilícelo, en lugar de crear uno por solicitud:
import { SoamtarClient } from '@soamtar/sdk'
const soamtar = new SoamtarClient(process.env.SOAMTAR_SECRET_KEY)
export function pay(order: { id: string; amount: string; phone: string }) {
return soamtar.payments.create({
merchant_ref: order.id,
amount: order.amount, // "1250.00" → Le 1,250.00
currency: 'SLE',
provider: 'orange_money_sl',
phone: order.phone, // +232XXXXXXXX
})
}Reintentos con backoff
Los SDK no reintentan por sí mismos. Si añade reintentos, reutilice la misma Idempotency-Key para que un POST repetido nunca cree un segundo pago:
import { randomUUID } from 'node:crypto'
async function withRetry<T>(fn: (key: string) => Promise<T>, max = 3): Promise<T> {
const idempotencyKey = randomUUID() // one key for every attempt
for (let attempt = 0; ; attempt++) {
try {
return await fn(idempotencyKey)
} catch (e: any) {
const retryable = !e.status || e.status === 429 || e.status >= 500
if (!retryable || attempt >= max) throw e
await new Promise(r => setTimeout(r, 2 ** attempt * 1000)) // 1s, 2s, 4s
}
}
}
await withRetry(key => soamtar.payments.create(params, { idempotencyKey: key }))Importante
Reintente los errores de red, 429 y 5xx con la misma Idempotency-Key. Nunca reintente los demás 4xx: corrija primero la solicitud. Consulte Idempotency (en inglés).
Generar a partir de la especificación OpenAPI
Para un lenguaje sin SDK, genere un cliente tipado a partir de la especificación OpenAPI (openapi.yaml):
# TypeScript types
npx openapi-typescript ./openapi.yaml -o src/soamtar.types.ts
# Python (openapi-generator)
openapi-generator-cli generate -i ./openapi.yaml -g python -o ./soamtar-py
# Go
oapi-codegen -package soamtar ./openapi.yaml > soamtar.gen.goSolicitar un SDK
¿Falta su lenguaje? Escriba a support@so-amtar.com indicando:
- el lenguaje / framework de destino;
- su volumen de transacciones previsto;
- su caso de uso principal.