Instalar el SDK en Go
| Módulo | bitbucket.org/summabit/spidi-sdk-go |
| Entorno mínimo | Go 1.22+ |
| Distribución | Módulo privado de Git, con llaves SSH y variable de entorno |
Lo que necesitas antes de empezar
- Una llave SSH autorizada en el repositorio, que habilita SPIDI.
- Un
session_idde prueba, creado por tu backend, por el monto mínimo. - Datos de un pagador real: cédula, teléfono y banco venezolanos, asociados entre sí.
Paso 1 · Configura el acceso al módulo privado
Redirige las peticiones HTTPS a SSH:
git config --global url."git@bitbucket.org:".insteadOf "https://bitbucket.org/"
Y declara el módulo como privado, para que Go no lo busque en el proxy público:
# En Linux / macOS:
export GOPRIVATE=bitbucket.org/summabit/*
# En Windows (PowerShell):
$env:GOPRIVATE = "bitbucket.org/summabit/*"
Paso 2 · Declara la dependencia
go get bitbucket.org/summabit/spidi-sdk-go@v0.2.0
Paso 3 · Tu primera llamada
package main
import (
"context"
"fmt"
"log"
"bitbucket.org/summabit/spidi-sdk-go/spidi"
)
func main() {
client := spidi.New(spidi.Options{}) // Environment.Production por defecto
ctx := context.Background()
sessionResponse, err := client.GetSession(ctx, "tu_session_id")
if err != nil {
log.Fatalf("Error al obtener sesión: %v", err)
}
session := sessionResponse.Data
if spidi.IsPaidSession(sessionResponse) {
fmt.Println("La sesión ya fue pagada con anterioridad")
return
}
fmt.Printf("Monto a pagar: Bs. %s (USD %s)\\n",
spidi.FormatAmount(session.BsAmount, 2), spidi.FormatAmount(session.USDAmount, 2))
}
Paso 4 · El flujo del débito inmediato
4.1 — Prepara los datos
identification := spidi.BuildIdentification(spidi.Cedula, "12345678") // V12345678
instrument := spidi.BuildInstrument("0412", "1234567") // 04121234567
banks, _ := client.GetBanks(ctx)
bank := banks[0]
pos, _ := client.GetPosCommerce(ctx, session.PosCommerceAlias)
tx, err := client.CreateTransaction(ctx, spidi.CreateTransactionInput{
Identification: identification,
Amount: spidi.FormatBsAmount(session.BsAmount), // "10,00" (con coma)
BankCode: bank.Code, // "0102"
Instrument: instrument, // teléfono del pagador
PosCommerceID: pos.Data.ID,
})
if err != nil {
log.Fatalf("Error al crear transacción: %v", err)
}
4.2 — Crea la transacción y guarda la sesión antes de confirmar
transaction := spidi.SpidiTransaction{
TransactionID: tx.TransactionID,
USDAmount: session.USDAmount,
BsAmount: session.BsAmount,
BCVRate: session.BCVRate,
PayerPaymentID: identification,
PayerPaymentPhone: instrument,
BankID: bank.ID, // UUID del banco
SpidiSessionID: session.ID,
SpidiCommerceAlias: session.SpidiCommerceAlias,
PosCommerceAlias: session.PosCommerceAlias,
MainCurrency: session.MainCurrency,
SpidiID: tx.SpidiID,
}
_, err = client.SaveSession(ctx, spidi.SaveSessionInput{
ID: session.ID,
USDAmount: transaction.USDAmount,
BsAmount: transaction.BsAmount,
BCVRate: transaction.BCVRate,
SpidiCommerceAlias: transaction.SpidiCommerceAlias,
PosCommerceAlias: transaction.PosCommerceAlias,
MainCurrency: transaction.MainCurrency,
TransactionID: transaction.TransactionID,
PayerPaymentID: transaction.PayerPaymentID,
PayerPaymentPhone: transaction.PayerPaymentPhone,
BankID: transaction.BankID,
SpidiID: transaction.SpidiID,
})
4.3 — Confirma el pago. Aquí sale el dinero, y esta llamada no se reintenta:
res, err := client.ConfirmPayment(ctx, tx.TransactionID, spidi.ConfirmPaymentInput{
Key: "clave_SMS_recibida",
SpidiTransaction: transaction,
})
if err != nil {
// IMPORTANTE: Ante errores de Red o Timeout, NUNCA reintentes ConfirmPayment.
// Consulta el estado de la transacción de forma segura:
status, statusErr := client.GetTransactionStatus(ctx, session.ID)
log.Fatalf("Confirmación ambigua: %v. Estado real: %v (%v)", err, status.Status, statusErr)
}
if rejection := res.Rejection(); rejection != nil {
log.Fatalf("El banco rechazó la transacción (%s): %s", rejection.CodeID, rejection.UserDescription)
}
fmt.Printf("¡Pago exitoso! Referencia bancaria: %s\\n", res.Data.ID)
Cripto vía Binance Pay
// Crear orden cripto
order, err := client.CreateCryptoOrder(ctx, session.ID, session.BsAmount)
// Verificar estado de la orden antes de acreditar
status, err := client.GetCryptoOrderStatus(ctx, order.CrixtoOrderID)
if status == "PAID" {
// Acreditar el pago
result, err := client.ConfirmCryptoPayment(ctx, order.CrixtoOrderID, transaction)
}
Las reglas que no cambian entre plataformas
Los formatos de monto, los dos identificadores del banco, la validación y —sobre todo— la regla de que la confirmación del débito no se reintenta nunca son idénticos en las cuatro. Viven en una sola página para que no se lean a medias:
→ El contrato y los errores · Antes de tocar dinero real
Del documento de integración que entrega SPIDI, de agosto de 2026, copiado literal. No lo hemos ejecutado: el paquete es privado y no tenemos acceso. A diferencia del resto de este portal, aquí no hay una prueba que lo respalde.