santimpay direct payment
This commit is contained in:
parent
f32331bcdb
commit
d40bdcf33c
|
|
@ -153,7 +153,7 @@ func main() {
|
||||||
virtualGameSvc := virtualgameservice.New(vitualGameRepo, *walletSvc, store, cfg, logger)
|
virtualGameSvc := virtualgameservice.New(vitualGameRepo, *walletSvc, store, cfg, logger)
|
||||||
aleaService := alea.NewAleaPlayService(vitualGameRepo, *walletSvc, cfg, logger)
|
aleaService := alea.NewAleaPlayService(vitualGameRepo, *walletSvc, cfg, logger)
|
||||||
veliCLient := veli.NewClient(cfg, walletSvc)
|
veliCLient := veli.NewClient(cfg, walletSvc)
|
||||||
veliVirtualGameService := veli.New(veliCLient, walletSvc,cfg)
|
veliVirtualGameService := veli.New(veliCLient, walletSvc, cfg)
|
||||||
recommendationSvc := recommendation.NewService(recommendationRepo)
|
recommendationSvc := recommendation.NewService(recommendationRepo)
|
||||||
chapaClient := chapa.NewClient(cfg.CHAPA_BASE_URL, cfg.CHAPA_SECRET_KEY)
|
chapaClient := chapa.NewClient(cfg.CHAPA_BASE_URL, cfg.CHAPA_SECRET_KEY)
|
||||||
|
|
||||||
|
|
@ -239,7 +239,7 @@ func main() {
|
||||||
|
|
||||||
santimpayClient := santimpay.NewSantimPayClient(cfg)
|
santimpayClient := santimpay.NewSantimPayClient(cfg)
|
||||||
|
|
||||||
santimpaySvc := santimpay.NewSantimPayService(santimpayClient, cfg, transferStore)
|
santimpaySvc := santimpay.NewSantimPayService(santimpayClient, cfg, transferStore, walletSvc)
|
||||||
telebirrSvc := telebirr.NewTelebirrService(cfg, transferStore, walletSvc)
|
telebirrSvc := telebirr.NewTelebirrService(cfg, transferStore, walletSvc)
|
||||||
|
|
||||||
// Initialize and start HTTP server
|
// Initialize and start HTTP server
|
||||||
|
|
|
||||||
464
docs/docs.go
464
docs/docs.go
|
|
@ -4311,6 +4311,173 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/v1/santimpay/b2c-withdrawal": {
|
||||||
|
"post": {
|
||||||
|
"description": "Initiates a B2C withdrawal request with SantimPay and returns the response.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"SantimPay"
|
||||||
|
],
|
||||||
|
"summary": "Process SantimPay B2C Withdrawal",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "SantimPay B2C withdrawal request payload",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.GeneratePaymentURLRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/santimpay/b2c/partners": {
|
||||||
|
"get": {
|
||||||
|
"description": "Fetches a list of available B2C payout partners (e.g., Telebirr, Mpesa, Banks) from SantimPay.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"SantimPay"
|
||||||
|
],
|
||||||
|
"summary": "Get SantimPay B2C Partners",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/santimpay/callback": {
|
||||||
|
"post": {
|
||||||
|
"description": "Processes a callback from SantimPay, updates transfer status, and credits user wallet if payment was successful.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"SantimPay"
|
||||||
|
],
|
||||||
|
"summary": "Process SantimPay Payment Callback",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "SantimPay callback payload",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.SantimPayCallbackPayload"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/santimpay/direct-payment": {
|
||||||
|
"post": {
|
||||||
|
"description": "Initiates a direct payment request with SantimPay and returns the response.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"SantimPay"
|
||||||
|
],
|
||||||
|
"summary": "Process SantimPay Direct Payment",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "SantimPay direct payment request payload",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.GeneratePaymentURLRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v1/santimpay/payment": {
|
"/api/v1/santimpay/payment": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Generates a payment URL using SantimPay and returns it to the client.",
|
"description": "Generates a payment URL using SantimPay and returns it to the client.",
|
||||||
|
|
@ -4331,7 +4498,53 @@ const docTemplate = `{
|
||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/domain.GeneratePaymentURLInput"
|
"$ref": "#/definitions/domain.GeneratePaymentURLRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/santimpay/transaction-status": {
|
||||||
|
"post": {
|
||||||
|
"description": "Retrieves the real-time status of a transaction from SantimPay.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"SantimPay"
|
||||||
|
],
|
||||||
|
"summary": "Check SantimPay Transaction Status",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Transaction status request payload",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.TransactionStatusRequest"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -5434,7 +5647,7 @@ const docTemplate = `{
|
||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/domain.GeneratePaymentURLInput"
|
"$ref": "#/definitions/domain.GeneratePaymentURLRequest"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -6443,6 +6656,64 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/v1/veli/huge-wins": {
|
||||||
|
"post": {
|
||||||
|
"description": "Retrieves huge win transactions based on brand configuration (e.g. win \u003e 10000 USD or 100x bet)",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Virtual Games - VeliGames"
|
||||||
|
],
|
||||||
|
"summary": "Get Veli Huge Wins",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Huge Wins Request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.HugeWinsRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/domain.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/domain.HugeWinsResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v1/veli/providers": {
|
"/api/v1/veli/providers": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Retrieves the list of VeliGames providers",
|
"description": "Retrieves the list of VeliGames providers",
|
||||||
|
|
@ -8270,10 +8541,6 @@ const docTemplate = `{
|
||||||
"domain.GamingActivityRequest": {
|
"domain.GamingActivityRequest": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"brandId": {
|
|
||||||
"description": "Required",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"currencies": {
|
"currencies": {
|
||||||
"description": "Optional",
|
"description": "Optional",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
|
@ -8335,20 +8602,20 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"domain.GeneratePaymentURLInput": {
|
"domain.GeneratePaymentURLRequest": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"amount": {
|
"amount": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"id": {
|
"paymentMethod": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"paymentReason": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"phoneNumber": {
|
"phoneNumber": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
|
||||||
"reason": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -8401,6 +8668,108 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"domain.HugeWinItem": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"betAmount": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"betAmountUsd": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"betTransactionId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"brandId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"correlationId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"currency": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"gameId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"operatorId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"playerId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"providerId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"reason": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"roundId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"winAmount": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"winAmountUsd": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"winTransactionId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"domain.HugeWinsRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"brandId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"currencies": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fromDate": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"gameIds": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"page": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"providerId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"toDate": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"domain.HugeWinsResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/domain.HugeWinItem"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"$ref": "#/definitions/domain.PaginationMeta"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"domain.InstResponse": {
|
"domain.InstResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
@ -8919,6 +9288,68 @@ const docTemplate = `{
|
||||||
"RoleCashier"
|
"RoleCashier"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"domain.SantimPayCallbackPayload": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"accountNumber": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"address": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"amount": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"currency": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"failureRedirectUrl": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"merId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"merName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"msisdn": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"paymentVia": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"reason": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"receiverWalletID": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"refId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"successRedirectUrl": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"thirdPartyId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"txnId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"domain.ShopBetReq": {
|
"domain.ShopBetReq": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
@ -9383,6 +9814,17 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"domain.TransactionStatusRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"fullParams": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"domain.UpcomingEvent": {
|
"domain.UpcomingEvent": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
||||||
|
|
@ -4303,6 +4303,173 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/v1/santimpay/b2c-withdrawal": {
|
||||||
|
"post": {
|
||||||
|
"description": "Initiates a B2C withdrawal request with SantimPay and returns the response.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"SantimPay"
|
||||||
|
],
|
||||||
|
"summary": "Process SantimPay B2C Withdrawal",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "SantimPay B2C withdrawal request payload",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.GeneratePaymentURLRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/santimpay/b2c/partners": {
|
||||||
|
"get": {
|
||||||
|
"description": "Fetches a list of available B2C payout partners (e.g., Telebirr, Mpesa, Banks) from SantimPay.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"SantimPay"
|
||||||
|
],
|
||||||
|
"summary": "Get SantimPay B2C Partners",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/santimpay/callback": {
|
||||||
|
"post": {
|
||||||
|
"description": "Processes a callback from SantimPay, updates transfer status, and credits user wallet if payment was successful.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"SantimPay"
|
||||||
|
],
|
||||||
|
"summary": "Process SantimPay Payment Callback",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "SantimPay callback payload",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.SantimPayCallbackPayload"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/santimpay/direct-payment": {
|
||||||
|
"post": {
|
||||||
|
"description": "Initiates a direct payment request with SantimPay and returns the response.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"SantimPay"
|
||||||
|
],
|
||||||
|
"summary": "Process SantimPay Direct Payment",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "SantimPay direct payment request payload",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.GeneratePaymentURLRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v1/santimpay/payment": {
|
"/api/v1/santimpay/payment": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Generates a payment URL using SantimPay and returns it to the client.",
|
"description": "Generates a payment URL using SantimPay and returns it to the client.",
|
||||||
|
|
@ -4323,7 +4490,53 @@
|
||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/domain.GeneratePaymentURLInput"
|
"$ref": "#/definitions/domain.GeneratePaymentURLRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/santimpay/transaction-status": {
|
||||||
|
"post": {
|
||||||
|
"description": "Retrieves the real-time status of a transaction from SantimPay.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"SantimPay"
|
||||||
|
],
|
||||||
|
"summary": "Check SantimPay Transaction Status",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Transaction status request payload",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.TransactionStatusRequest"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -5426,7 +5639,7 @@
|
||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/domain.GeneratePaymentURLInput"
|
"$ref": "#/definitions/domain.GeneratePaymentURLRequest"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -6435,6 +6648,64 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/v1/veli/huge-wins": {
|
||||||
|
"post": {
|
||||||
|
"description": "Retrieves huge win transactions based on brand configuration (e.g. win \u003e 10000 USD or 100x bet)",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Virtual Games - VeliGames"
|
||||||
|
],
|
||||||
|
"summary": "Get Veli Huge Wins",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Huge Wins Request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.HugeWinsRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/domain.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/domain.HugeWinsResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/domain.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v1/veli/providers": {
|
"/api/v1/veli/providers": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Retrieves the list of VeliGames providers",
|
"description": "Retrieves the list of VeliGames providers",
|
||||||
|
|
@ -8262,10 +8533,6 @@
|
||||||
"domain.GamingActivityRequest": {
|
"domain.GamingActivityRequest": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"brandId": {
|
|
||||||
"description": "Required",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"currencies": {
|
"currencies": {
|
||||||
"description": "Optional",
|
"description": "Optional",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
|
@ -8327,20 +8594,20 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"domain.GeneratePaymentURLInput": {
|
"domain.GeneratePaymentURLRequest": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"amount": {
|
"amount": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"id": {
|
"paymentMethod": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"paymentReason": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"phoneNumber": {
|
"phoneNumber": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
|
||||||
"reason": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -8393,6 +8660,108 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"domain.HugeWinItem": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"betAmount": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"betAmountUsd": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"betTransactionId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"brandId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"correlationId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"createdAt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"currency": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"gameId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"operatorId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"playerId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"providerId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"reason": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"roundId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"winAmount": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"winAmountUsd": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"winTransactionId": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"domain.HugeWinsRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"brandId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"currencies": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fromDate": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"gameIds": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"page": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"providerId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"toDate": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"domain.HugeWinsResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/domain.HugeWinItem"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"$ref": "#/definitions/domain.PaginationMeta"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"domain.InstResponse": {
|
"domain.InstResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
@ -8911,6 +9280,68 @@
|
||||||
"RoleCashier"
|
"RoleCashier"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"domain.SantimPayCallbackPayload": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"accountNumber": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"address": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"amount": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"currency": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"failureRedirectUrl": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"merId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"merName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"msisdn": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"paymentVia": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"reason": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"receiverWalletID": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"refId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"successRedirectUrl": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"thirdPartyId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"txnId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"domain.ShopBetReq": {
|
"domain.ShopBetReq": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
@ -9375,6 +9806,17 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"domain.TransactionStatusRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"fullParams": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"domain.UpcomingEvent": {
|
"domain.UpcomingEvent": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
||||||
|
|
@ -770,9 +770,6 @@ definitions:
|
||||||
type: object
|
type: object
|
||||||
domain.GamingActivityRequest:
|
domain.GamingActivityRequest:
|
||||||
properties:
|
properties:
|
||||||
brandId:
|
|
||||||
description: Required
|
|
||||||
type: string
|
|
||||||
currencies:
|
currencies:
|
||||||
description: Optional
|
description: Optional
|
||||||
items:
|
items:
|
||||||
|
|
@ -816,16 +813,16 @@ definitions:
|
||||||
meta:
|
meta:
|
||||||
$ref: '#/definitions/domain.PaginationMeta'
|
$ref: '#/definitions/domain.PaginationMeta'
|
||||||
type: object
|
type: object
|
||||||
domain.GeneratePaymentURLInput:
|
domain.GeneratePaymentURLRequest:
|
||||||
properties:
|
properties:
|
||||||
amount:
|
amount:
|
||||||
type: integer
|
type: integer
|
||||||
id:
|
paymentMethod:
|
||||||
|
type: string
|
||||||
|
paymentReason:
|
||||||
type: string
|
type: string
|
||||||
phoneNumber:
|
phoneNumber:
|
||||||
type: string
|
type: string
|
||||||
reason:
|
|
||||||
type: string
|
|
||||||
type: object
|
type: object
|
||||||
domain.GetCompanyRes:
|
domain.GetCompanyRes:
|
||||||
properties:
|
properties:
|
||||||
|
|
@ -863,6 +860,73 @@ definitions:
|
||||||
example: 1
|
example: 1
|
||||||
type: integer
|
type: integer
|
||||||
type: object
|
type: object
|
||||||
|
domain.HugeWinItem:
|
||||||
|
properties:
|
||||||
|
betAmount:
|
||||||
|
type: number
|
||||||
|
betAmountUsd:
|
||||||
|
type: number
|
||||||
|
betTransactionId:
|
||||||
|
type: string
|
||||||
|
brandId:
|
||||||
|
type: string
|
||||||
|
correlationId:
|
||||||
|
type: string
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
currency:
|
||||||
|
type: string
|
||||||
|
gameId:
|
||||||
|
type: string
|
||||||
|
operatorId:
|
||||||
|
type: string
|
||||||
|
playerId:
|
||||||
|
type: string
|
||||||
|
providerId:
|
||||||
|
type: string
|
||||||
|
reason:
|
||||||
|
type: string
|
||||||
|
roundId:
|
||||||
|
type: string
|
||||||
|
winAmount:
|
||||||
|
type: number
|
||||||
|
winAmountUsd:
|
||||||
|
type: number
|
||||||
|
winTransactionId:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
domain.HugeWinsRequest:
|
||||||
|
properties:
|
||||||
|
brandId:
|
||||||
|
type: string
|
||||||
|
currencies:
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
fromDate:
|
||||||
|
type: string
|
||||||
|
gameIds:
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
page:
|
||||||
|
type: integer
|
||||||
|
providerId:
|
||||||
|
type: string
|
||||||
|
size:
|
||||||
|
type: integer
|
||||||
|
toDate:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
domain.HugeWinsResponse:
|
||||||
|
properties:
|
||||||
|
items:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/domain.HugeWinItem'
|
||||||
|
type: array
|
||||||
|
meta:
|
||||||
|
$ref: '#/definitions/domain.PaginationMeta'
|
||||||
|
type: object
|
||||||
domain.InstResponse:
|
domain.InstResponse:
|
||||||
properties:
|
properties:
|
||||||
data:
|
data:
|
||||||
|
|
@ -1217,6 +1281,47 @@ definitions:
|
||||||
- RoleBranchManager
|
- RoleBranchManager
|
||||||
- RoleCustomer
|
- RoleCustomer
|
||||||
- RoleCashier
|
- RoleCashier
|
||||||
|
domain.SantimPayCallbackPayload:
|
||||||
|
properties:
|
||||||
|
accountNumber:
|
||||||
|
type: string
|
||||||
|
address:
|
||||||
|
type: string
|
||||||
|
amount:
|
||||||
|
type: string
|
||||||
|
created_at:
|
||||||
|
type: string
|
||||||
|
currency:
|
||||||
|
type: string
|
||||||
|
failureRedirectUrl:
|
||||||
|
type: string
|
||||||
|
merId:
|
||||||
|
type: string
|
||||||
|
merName:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
msisdn:
|
||||||
|
type: string
|
||||||
|
paymentVia:
|
||||||
|
type: string
|
||||||
|
reason:
|
||||||
|
type: string
|
||||||
|
receiverWalletID:
|
||||||
|
type: string
|
||||||
|
refId:
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
successRedirectUrl:
|
||||||
|
type: string
|
||||||
|
thirdPartyId:
|
||||||
|
type: string
|
||||||
|
txnId:
|
||||||
|
type: string
|
||||||
|
updated_at:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
domain.ShopBetReq:
|
domain.ShopBetReq:
|
||||||
properties:
|
properties:
|
||||||
account_name:
|
account_name:
|
||||||
|
|
@ -1543,6 +1648,13 @@ definitions:
|
||||||
example: 4.22
|
example: 4.22
|
||||||
type: number
|
type: number
|
||||||
type: object
|
type: object
|
||||||
|
domain.TransactionStatusRequest:
|
||||||
|
properties:
|
||||||
|
fullParams:
|
||||||
|
type: boolean
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
domain.UpcomingEvent:
|
domain.UpcomingEvent:
|
||||||
properties:
|
properties:
|
||||||
away_kit_image:
|
away_kit_image:
|
||||||
|
|
@ -5200,6 +5312,119 @@ paths:
|
||||||
summary: Get results for an event
|
summary: Get results for an event
|
||||||
tags:
|
tags:
|
||||||
- result
|
- result
|
||||||
|
/api/v1/santimpay/b2c-withdrawal:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Initiates a B2C withdrawal request with SantimPay and returns the
|
||||||
|
response.
|
||||||
|
parameters:
|
||||||
|
- description: SantimPay B2C withdrawal request payload
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.GeneratePaymentURLRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.Response'
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.ErrorResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.ErrorResponse'
|
||||||
|
summary: Process SantimPay B2C Withdrawal
|
||||||
|
tags:
|
||||||
|
- SantimPay
|
||||||
|
/api/v1/santimpay/b2c/partners:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Fetches a list of available B2C payout partners (e.g., Telebirr,
|
||||||
|
Mpesa, Banks) from SantimPay.
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.Response'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.ErrorResponse'
|
||||||
|
summary: Get SantimPay B2C Partners
|
||||||
|
tags:
|
||||||
|
- SantimPay
|
||||||
|
/api/v1/santimpay/callback:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Processes a callback from SantimPay, updates transfer status, and
|
||||||
|
credits user wallet if payment was successful.
|
||||||
|
parameters:
|
||||||
|
- description: SantimPay callback payload
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.SantimPayCallbackPayload'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.Response'
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.ErrorResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.ErrorResponse'
|
||||||
|
summary: Process SantimPay Payment Callback
|
||||||
|
tags:
|
||||||
|
- SantimPay
|
||||||
|
/api/v1/santimpay/direct-payment:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Initiates a direct payment request with SantimPay and returns the
|
||||||
|
response.
|
||||||
|
parameters:
|
||||||
|
- description: SantimPay direct payment request payload
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.GeneratePaymentURLRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.Response'
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.ErrorResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.ErrorResponse'
|
||||||
|
summary: Process SantimPay Direct Payment
|
||||||
|
tags:
|
||||||
|
- SantimPay
|
||||||
/api/v1/santimpay/payment:
|
/api/v1/santimpay/payment:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
|
|
@ -5211,7 +5436,7 @@ paths:
|
||||||
name: request
|
name: request
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/domain.GeneratePaymentURLInput'
|
$ref: '#/definitions/domain.GeneratePaymentURLRequest'
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
|
|
@ -5230,6 +5455,36 @@ paths:
|
||||||
summary: Create SantimPay Payment Session
|
summary: Create SantimPay Payment Session
|
||||||
tags:
|
tags:
|
||||||
- SantimPay
|
- SantimPay
|
||||||
|
/api/v1/santimpay/transaction-status:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Retrieves the real-time status of a transaction from SantimPay.
|
||||||
|
parameters:
|
||||||
|
- description: Transaction status request payload
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.TransactionStatusRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.Response'
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.ErrorResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.ErrorResponse'
|
||||||
|
summary: Check SantimPay Transaction Status
|
||||||
|
tags:
|
||||||
|
- SantimPay
|
||||||
/api/v1/search/branch:
|
/api/v1/search/branch:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
|
|
@ -5936,7 +6191,7 @@ paths:
|
||||||
name: request
|
name: request
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/domain.GeneratePaymentURLInput'
|
$ref: '#/definitions/domain.GeneratePaymentURLRequest'
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
|
|
@ -6593,6 +6848,42 @@ paths:
|
||||||
summary: Get Veli Gaming Activity
|
summary: Get Veli Gaming Activity
|
||||||
tags:
|
tags:
|
||||||
- Virtual Games - VeliGames
|
- Virtual Games - VeliGames
|
||||||
|
/api/v1/veli/huge-wins:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Retrieves huge win transactions based on brand configuration (e.g.
|
||||||
|
win > 10000 USD or 100x bet)
|
||||||
|
parameters:
|
||||||
|
- description: Huge Wins Request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.HugeWinsRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/domain.Response'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/domain.HugeWinsResponse'
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.ErrorResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/domain.ErrorResponse'
|
||||||
|
summary: Get Veli Huge Wins
|
||||||
|
tags:
|
||||||
|
- Virtual Games - VeliGames
|
||||||
/api/v1/veli/providers:
|
/api/v1/veli/providers:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
|
|
|
||||||
|
|
@ -83,8 +83,11 @@ type ARIFPAYConfig struct {
|
||||||
|
|
||||||
type SANTIMPAYConfig struct {
|
type SANTIMPAYConfig struct {
|
||||||
SecretKey string `mapstructure:"secret_key"`
|
SecretKey string `mapstructure:"secret_key"`
|
||||||
MerchantID string `mapstructure:"merchant_id"`
|
MerchantID string `mapstructure:"merchantId"`
|
||||||
BaseURL string `mapstructure:"base_url"`
|
BaseURL string `mapstructure:"base_url"`
|
||||||
|
NotifyURL string `mapstructure:"notifyUrl"`
|
||||||
|
CancelUrl string `mapstructure:"cancelUrl"`
|
||||||
|
SuccessUrl string `mapstructure:"successUrl"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TELEBIRRConfig struct {
|
type TELEBIRRConfig struct {
|
||||||
|
|
@ -254,7 +257,9 @@ func (c *Config) loadEnv() error {
|
||||||
|
|
||||||
c.SANTIMPAY.SecretKey = os.Getenv("SANTIMPAY_SECRET_KEY")
|
c.SANTIMPAY.SecretKey = os.Getenv("SANTIMPAY_SECRET_KEY")
|
||||||
c.SANTIMPAY.MerchantID = os.Getenv("SANTIMPAY_MERCHANT_ID")
|
c.SANTIMPAY.MerchantID = os.Getenv("SANTIMPAY_MERCHANT_ID")
|
||||||
c.SANTIMPAY.BaseURL = os.Getenv("SANTIMPAY_Base_URL")
|
c.SANTIMPAY.BaseURL = os.Getenv("SANTIMPAY_BASE_URL")
|
||||||
|
c.SANTIMPAY.NotifyURL = os.Getenv("SANTIMPAY_NOTIFY_URL")
|
||||||
|
c.SANTIMPAY.CancelUrl = os.Getenv("SANTIMPAY_CANCEL_URL")
|
||||||
|
|
||||||
//Alea Play
|
//Alea Play
|
||||||
aleaEnabled := os.Getenv("ALEA_ENABLED")
|
aleaEnabled := os.Getenv("ALEA_ENABLED")
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,13 @@
|
||||||
package domain
|
package domain
|
||||||
|
|
||||||
type GeneratePaymentURLInput struct {
|
type GeneratePaymentURLRequest struct {
|
||||||
ID string
|
Amount int `json:"amount"`
|
||||||
Amount int
|
Reason string `json:"paymentReason"`
|
||||||
Reason string
|
PhoneNumber string `json:"phoneNumber"`
|
||||||
PhoneNumber string
|
PaymentMethod string `json:"paymentMethod,omitempty"`
|
||||||
// SuccessRedirectURL string
|
|
||||||
// FailureRedirectURL string
|
|
||||||
// CancelRedirectURL string
|
|
||||||
// NotifyURL string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type InitiatePaymentPayload struct {
|
type InitiatePaymentRequest struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Amount int `json:"amount"`
|
Amount int `json:"amount"`
|
||||||
Reason string `json:"paymentReason"`
|
Reason string `json:"paymentReason"`
|
||||||
|
|
@ -22,4 +18,64 @@ type InitiatePaymentPayload struct {
|
||||||
NotifyURL string `json:"notifyUrl"`
|
NotifyURL string `json:"notifyUrl"`
|
||||||
CancelRedirectURL string `json:"cancelRedirectUrl"`
|
CancelRedirectURL string `json:"cancelRedirectUrl"`
|
||||||
PhoneNumber string `json:"phoneNumber"`
|
PhoneNumber string `json:"phoneNumber"`
|
||||||
|
PaymentMethod string `json:"paymentMethod,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SantimPayCallbackPayload struct {
|
||||||
|
TxnId string `json:"txnId"`
|
||||||
|
CreatedAt string `json:"created_at"`
|
||||||
|
UpdatedAt string `json:"updated_at"`
|
||||||
|
ThirdPartyId string `json:"thirdPartyId"`
|
||||||
|
MerId string `json:"merId"`
|
||||||
|
MerName string `json:"merName"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
Amount string `json:"amount"`
|
||||||
|
Currency string `json:"currency"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
Msisdn string `json:"msisdn"`
|
||||||
|
AccountNumber string `json:"accountNumber"`
|
||||||
|
PaymentVia string `json:"paymentVia"`
|
||||||
|
RefId string `json:"refId"`
|
||||||
|
SuccessRedirectUrl string `json:"successRedirectUrl"`
|
||||||
|
FailureRedirectUrl string `json:"failureRedirectUrl"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
ReceiverWalletID string `json:"receiverWalletID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SantimTokenPayload struct {
|
||||||
|
Amount int `json:"amount"`
|
||||||
|
Reason string `json:"paymentReason"`
|
||||||
|
PaymentMethod string `json:"paymentMethod"`
|
||||||
|
PhoneNumber string `json:"phoneNumber"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Partner struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Input string `json:"input"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// B2CPartnersResponse is the top-level response
|
||||||
|
type B2CPartnersResponse struct {
|
||||||
|
Partners []Partner `json:"partners"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SantimpayB2CWithdrawalRequest struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
ClientReference string `json:"clientReference"`
|
||||||
|
Amount float64 `json:"amount"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
MerchantID string `json:"merchantId"`
|
||||||
|
SignedToken string `json:"signedToken"`
|
||||||
|
ReceiverAccountNumber string `json:"receiverAccountNumber"`
|
||||||
|
NotifyURL string `json:"notifyUrl"`
|
||||||
|
PaymentMethod string `json:"paymentMethod"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TransactionStatusRequest struct {
|
||||||
|
TransactionID string `json:"id"`
|
||||||
|
FullParams *bool `json:"fullParams,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
@ -5,11 +5,12 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SantimPayClient interface {
|
type SantimPayClient interface {
|
||||||
GenerateSignedToken(amount int, reason string) (string, error)
|
GenerateSignedToken(payload domain.SantimTokenPayload) (string, error)
|
||||||
CheckTransactionStatus(id string)
|
CheckTransactionStatus(id string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -23,17 +24,26 @@ func NewSantimPayClient(cfg *config.Config) SantimPayClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *santimClient) GenerateSignedToken(amount int, reason string) (string, error) {
|
func (c *santimClient) GenerateSignedToken(payload domain.SantimTokenPayload) (string, error) {
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
|
|
||||||
claims := jwt.MapClaims{
|
claims := jwt.MapClaims{
|
||||||
"amount": amount,
|
"amount": payload.Amount,
|
||||||
"paymentReason": reason,
|
"paymentReason": payload.Reason,
|
||||||
"merchantId": c.cfg.SANTIMPAY.MerchantID,
|
"merchantId": c.cfg.SANTIMPAY.MerchantID,
|
||||||
"generated": now,
|
"generated": now,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional fields
|
||||||
|
if payload.PaymentMethod != "" {
|
||||||
|
claims["paymentMethod"] = payload.PaymentMethod
|
||||||
|
}
|
||||||
|
if payload.PhoneNumber != "" {
|
||||||
|
claims["phoneNumber"] = payload.PhoneNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodES256, claims)
|
token := jwt.NewWithClaims(jwt.SigningMethodES256, claims)
|
||||||
|
|
||||||
privateKey, err := jwt.ParseECPrivateKeyFromPEM([]byte(c.cfg.SANTIMPAY.SecretKey))
|
privateKey, err := jwt.ParseECPrivateKeyFromPEM([]byte(c.cfg.SANTIMPAY.SecretKey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("invalid private key: %w", err)
|
return "", fmt.Errorf("invalid private key: %w", err)
|
||||||
|
|
@ -47,6 +57,7 @@ func (c *santimClient) GenerateSignedToken(amount int, reason string) (string, e
|
||||||
return signedToken, nil
|
return signedToken, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (c *santimClient) CheckTransactionStatus(id string) {
|
func (c *santimClient) CheckTransactionStatus(id string) {
|
||||||
// optional async checker — can log or poll transaction status
|
// optional async checker — can log or poll transaction status
|
||||||
fmt.Println("Checking transaction status for:", id)
|
fmt.Println("Checking transaction status for:", id)
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
|
@ -14,42 +16,51 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// type SantimPayService interface {
|
// type SantimPayService interface {
|
||||||
// GeneratePaymentURL(input domain.GeneratePaymentURLInput) (map[string]string, error)
|
// GeneratePaymentURL(req domain.GeneratePaymentURLreq) (map[string]string, error)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
type SantimPayService struct {
|
type SantimPayService struct {
|
||||||
client SantimPayClient
|
client SantimPayClient
|
||||||
cfg *config.Config
|
cfg *config.Config
|
||||||
transferStore wallet.TransferStore
|
transferStore wallet.TransferStore
|
||||||
|
walletSvc *wallet.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSantimPayService(client SantimPayClient, cfg *config.Config, transferStore wallet.TransferStore) *SantimPayService {
|
func NewSantimPayService(client SantimPayClient, cfg *config.Config, transferStore wallet.TransferStore, walletSvc *wallet.Service) *SantimPayService {
|
||||||
return &SantimPayService{
|
return &SantimPayService{
|
||||||
client: client,
|
client: client,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
transferStore: transferStore,
|
transferStore: transferStore,
|
||||||
|
walletSvc: walletSvc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SantimPayService) GeneratePaymentURL(input domain.GeneratePaymentURLInput) (map[string]string, error) {
|
func (s *SantimPayService) InitiatePayment(req domain.GeneratePaymentURLRequest) (map[string]string, error) {
|
||||||
paymentID := uuid.NewString()
|
paymentID := uuid.NewString()
|
||||||
|
|
||||||
token, err := s.client.GenerateSignedToken(input.Amount, input.Reason)
|
tokenPayload := domain.SantimTokenPayload{
|
||||||
|
Amount: req.Amount,
|
||||||
|
Reason: req.Reason,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Generate signed token (used as Bearer token in headers)
|
||||||
|
token, err := s.client.GenerateSignedToken(tokenPayload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("token generation failed: %w", err)
|
return nil, fmt.Errorf("token generation failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
payload := domain.InitiatePaymentPayload{
|
// 2. Prepare payload (without token in body)
|
||||||
|
payload := domain.InitiatePaymentRequest{
|
||||||
ID: paymentID,
|
ID: paymentID,
|
||||||
Amount: input.Amount,
|
Amount: req.Amount,
|
||||||
Reason: input.Reason,
|
Reason: req.Reason,
|
||||||
MerchantID: s.cfg.SANTIMPAY.MerchantID,
|
MerchantID: s.cfg.SANTIMPAY.MerchantID,
|
||||||
|
SuccessRedirectURL: s.cfg.SANTIMPAY.SuccessUrl,
|
||||||
|
FailureRedirectURL: s.cfg.SANTIMPAY.CancelUrl,
|
||||||
|
NotifyURL: s.cfg.SANTIMPAY.NotifyURL,
|
||||||
|
CancelRedirectURL: s.cfg.SANTIMPAY.CancelUrl,
|
||||||
|
PhoneNumber: req.PhoneNumber,
|
||||||
SignedToken: token,
|
SignedToken: token,
|
||||||
SuccessRedirectURL: s.cfg.ARIFPAY.SuccessUrl,
|
|
||||||
FailureRedirectURL: s.cfg.ARIFPAY.ErrorUrl,
|
|
||||||
NotifyURL: s.cfg.ARIFPAY.B2CNotifyUrl,
|
|
||||||
CancelRedirectURL: s.cfg.ARIFPAY.CancelUrl,
|
|
||||||
PhoneNumber: input.PhoneNumber,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonData, err := json.Marshal(payload)
|
jsonData, err := json.Marshal(payload)
|
||||||
|
|
@ -57,7 +68,16 @@ func (s *SantimPayService) GeneratePaymentURL(input domain.GeneratePaymentURLInp
|
||||||
return nil, fmt.Errorf("failed to marshal payload: %w", err)
|
return nil, fmt.Errorf("failed to marshal payload: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := http.Post(s.cfg.SANTIMPAY.BaseURL+"/initiate-payment", "application/json", bytes.NewBuffer(jsonData))
|
// 3. Prepare request with Bearer token header
|
||||||
|
httpReq, err := http.NewRequest("POST", s.cfg.SANTIMPAY.BaseURL+"/gateway/initiate-payment", bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create HTTP request: %w", err)
|
||||||
|
}
|
||||||
|
httpReq.Header.Set("Content-Type", "application/json")
|
||||||
|
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||||
|
|
||||||
|
client := &http.Client{Timeout: 15 * time.Second}
|
||||||
|
resp, err := client.Do(httpReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to send HTTP request: %w", err)
|
return nil, fmt.Errorf("failed to send HTTP request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -72,21 +92,324 @@ func (s *SantimPayService) GeneratePaymentURL(input domain.GeneratePaymentURLInp
|
||||||
return nil, fmt.Errorf("failed to decode response: %w", err)
|
return nil, fmt.Errorf("failed to decode response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save transfer
|
// 4. Save transfer
|
||||||
transfer := domain.CreateTransfer{
|
transfer := domain.CreateTransfer{
|
||||||
Amount: domain.Currency(input.Amount),
|
Amount: domain.Currency(req.Amount),
|
||||||
Verified: false,
|
Verified: false,
|
||||||
Type: domain.DEPOSIT,
|
Type: domain.DEPOSIT,
|
||||||
ReferenceNumber: paymentID,
|
ReferenceNumber: paymentID,
|
||||||
Status: string(domain.PaymentStatusPending),
|
Status: string(domain.PaymentStatusPending),
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := s.transferStore.CreateTransfer(context.Background(), transfer); err != nil {
|
if _, err := s.transferStore.CreateTransfer(context.Background(), transfer); err != nil {
|
||||||
return nil, fmt.Errorf("failed to create transfer: %w", err)
|
return nil, fmt.Errorf("failed to create transfer: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optionally check transaction status in a goroutine
|
// 5. Optionally check transaction status asynchronously
|
||||||
go s.client.CheckTransactionStatus(paymentID)
|
// go s.client.CheckTransactionStatus(paymentID)
|
||||||
|
|
||||||
|
return responseBody, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SantimPayService) ProcessCallback(ctx context.Context, payload domain.SantimPayCallbackPayload) error {
|
||||||
|
// 1. Parse amount
|
||||||
|
amount, err := strconv.ParseFloat(payload.Amount, 64)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid amount in callback: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Retrieve the corresponding transfer by txnId or refId
|
||||||
|
transfer, err := s.transferStore.GetTransferByReference(ctx, payload.TxnId)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to fetch transfer for txnId %s: %w", payload.TxnId, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Update transfer status based on callback status
|
||||||
|
switch payload.Status {
|
||||||
|
case "COMPLETED":
|
||||||
|
transfer.Status = string(domain.PaymentStatusSuccessful)
|
||||||
|
transfer.Verified = true
|
||||||
|
|
||||||
|
userID, err := strconv.ParseInt(payload.ThirdPartyId, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid ThirdPartyId '%s': %w", payload.ThirdPartyId, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
wallets, err := s.walletSvc.GetWalletsByUser(ctx, userID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get wallets for user %d: %w", userID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optionally, credit user wallet
|
||||||
|
if transfer.Type == domain.DEPOSIT {
|
||||||
|
if _, err := s.walletSvc.AddToWallet(
|
||||||
|
ctx,
|
||||||
|
wallets[0].ID,
|
||||||
|
domain.Currency(amount),
|
||||||
|
domain.ValidInt64{},
|
||||||
|
domain.TRANSFER_SANTIMPAY,
|
||||||
|
domain.PaymentDetails{
|
||||||
|
ReferenceNumber: domain.ValidString{
|
||||||
|
Value: payload.TxnId,
|
||||||
|
Valid: true,
|
||||||
|
},
|
||||||
|
BankNumber: domain.ValidString{},
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
); err != nil {
|
||||||
|
return fmt.Errorf("failed to credit wallet: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case "FAILED", "CANCELLED":
|
||||||
|
transfer.Status = string(domain.PaymentStatusFailed)
|
||||||
|
transfer.Verified = false
|
||||||
|
default:
|
||||||
|
// Unknown status
|
||||||
|
return fmt.Errorf("unknown callback status: %s", payload.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Save the updated transfer
|
||||||
|
if err := s.transferStore.UpdateTransferStatus(ctx, transfer.ID, string(domain.PaymentStatusCompleted)); err != nil {
|
||||||
|
return fmt.Errorf("failed to update transfer status: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.transferStore.UpdateTransferVerification(ctx, transfer.ID, true); err != nil {
|
||||||
|
return fmt.Errorf("failed to update transfer verification: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SantimPayService) ProcessDirectPayment(ctx context.Context, req domain.GeneratePaymentURLRequest) (map[string]any, error) {
|
||||||
|
paymentID := uuid.NewString()
|
||||||
|
|
||||||
|
tokenPayload := domain.SantimTokenPayload{
|
||||||
|
Amount: req.Amount,
|
||||||
|
Reason: req.Reason,
|
||||||
|
PaymentMethod: req.PaymentMethod,
|
||||||
|
PhoneNumber: req.PhoneNumber,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Generate signed token for direct payment
|
||||||
|
token, err := s.client.GenerateSignedToken(tokenPayload)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to generate signed token: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Build payload
|
||||||
|
payload := domain.InitiatePaymentRequest{
|
||||||
|
ID: paymentID,
|
||||||
|
Amount: req.Amount,
|
||||||
|
Reason: req.Reason,
|
||||||
|
MerchantID: s.cfg.SANTIMPAY.MerchantID,
|
||||||
|
SignedToken: token,
|
||||||
|
PhoneNumber: req.PhoneNumber,
|
||||||
|
NotifyURL: s.cfg.SANTIMPAY.NotifyURL,
|
||||||
|
PaymentMethod: req.PaymentMethod,
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to marshal payload: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Prepare HTTP request
|
||||||
|
httpReq, err := http.NewRequest("POST", s.cfg.SANTIMPAY.BaseURL+"/direct-payment", bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create HTTP request: %w", err)
|
||||||
|
}
|
||||||
|
httpReq.Header.Set("Content-Type", "application/json")
|
||||||
|
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||||
|
|
||||||
|
client := &http.Client{Timeout: 15 * time.Second}
|
||||||
|
resp, err := client.Do(httpReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to send HTTP request: %w", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, fmt.Errorf("non-200 status code received: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Decode response
|
||||||
|
var responseBody map[string]any
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&responseBody); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to decode response: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Save transfer in DB
|
||||||
|
transfer := domain.CreateTransfer{
|
||||||
|
Amount: domain.Currency(req.Amount),
|
||||||
|
Verified: false,
|
||||||
|
Type: domain.DEPOSIT,
|
||||||
|
ReferenceNumber: paymentID,
|
||||||
|
Status: string(domain.PaymentStatusPending),
|
||||||
|
}
|
||||||
|
if _, err := s.transferStore.CreateTransfer(context.Background(), transfer); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create transfer: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. Optionally check transaction status async
|
||||||
|
// go s.client.CheckTransactionStatus(paymentID)
|
||||||
|
|
||||||
|
return responseBody, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SantimPayService) GetB2CPartners(ctx context.Context) (*domain.B2CPartnersResponse, error) {
|
||||||
|
url := fmt.Sprintf("%s/api/v1/gateway/payout/partners", s.cfg.SANTIMPAY.BaseURL)
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create request: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
HTTPClient := &http.Client{Timeout: 15 * time.Second}
|
||||||
|
|
||||||
|
resp, err := HTTPClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to call SantimPay API: %w", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
var partnersResp domain.B2CPartnersResponse
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&partnersResp); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to decode response: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &partnersResp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SantimPayService) ProcessB2CWithdrawal(ctx context.Context, req domain.GeneratePaymentURLRequest, userId int64) (map[string]any, error) {
|
||||||
|
|
||||||
|
transactID := uuid.NewString()
|
||||||
|
|
||||||
|
// 1. Generate signed token for B2C
|
||||||
|
tokenPayload := domain.SantimTokenPayload{
|
||||||
|
Amount: req.Amount,
|
||||||
|
Reason: req.Reason,
|
||||||
|
PaymentMethod: req.PaymentMethod,
|
||||||
|
PhoneNumber: req.PhoneNumber,
|
||||||
|
}
|
||||||
|
|
||||||
|
signedToken, err := s.client.GenerateSignedToken(tokenPayload)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to generate signed token for B2C: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Build payload
|
||||||
|
payload := domain.SantimpayB2CWithdrawalRequest{
|
||||||
|
ID: transactID,
|
||||||
|
ClientReference: string(rune(userId)),
|
||||||
|
Amount: float64(req.Amount),
|
||||||
|
Reason: req.Reason,
|
||||||
|
MerchantID: s.cfg.SANTIMPAY.MerchantID,
|
||||||
|
SignedToken: signedToken,
|
||||||
|
ReceiverAccountNumber: req.PhoneNumber,
|
||||||
|
NotifyURL: s.cfg.SANTIMPAY.NotifyURL,
|
||||||
|
PaymentMethod: req.PaymentMethod,
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to marshal B2C payload: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Send HTTP request
|
||||||
|
url := s.cfg.SANTIMPAY.BaseURL + "/payout-transfer"
|
||||||
|
httpReq, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create B2C request: %w", err)
|
||||||
|
}
|
||||||
|
httpReq.Header.Set("Content-Type", "application/json")
|
||||||
|
httpReq.Header.Set("Authorization", "Bearer "+signedToken)
|
||||||
|
|
||||||
|
client := &http.Client{Timeout: 15 * time.Second}
|
||||||
|
resp, err := client.Do(httpReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to send B2C request: %w", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, fmt.Errorf("B2C request failed with status code: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Decode response
|
||||||
|
var responseBody map[string]any
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&responseBody); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to decode B2C response: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Persist withdrawal record in DB
|
||||||
|
withdrawal := domain.CreateTransfer{
|
||||||
|
Amount: domain.Currency(req.Amount),
|
||||||
|
Verified: false,
|
||||||
|
Type: domain.WITHDRAW,
|
||||||
|
ReferenceNumber: transactID,
|
||||||
|
Status: string(domain.PaymentStatusPending),
|
||||||
|
}
|
||||||
|
if _, err := s.transferStore.CreateTransfer(context.Background(), withdrawal); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create withdrawal transfer: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return responseBody, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SantimPayService) CheckTransactionStatus(ctx context.Context, req domain.TransactionStatusRequest) (map[string]any, error) {
|
||||||
|
// 1. Generate signed token for status check
|
||||||
|
tokenPayload := domain.SantimTokenPayload{
|
||||||
|
ID: req.TransactionID,
|
||||||
|
}
|
||||||
|
|
||||||
|
signedToken, err := s.client.GenerateSignedToken(tokenPayload)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to generate signed token for transaction status: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Build request payload
|
||||||
|
payload := map[string]any{
|
||||||
|
"id": req.TransactionID,
|
||||||
|
"merchantId": s.cfg.SANTIMPAY.MerchantID,
|
||||||
|
"signedToken": signedToken,
|
||||||
|
"fullParams": req.FullParams,
|
||||||
|
"generated": time.Now().Unix(),
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to marshal transaction status payload: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Send HTTP request
|
||||||
|
url := s.cfg.SANTIMPAY.BaseURL + "/fetch-transaction-status"
|
||||||
|
httpReq, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create transaction status request: %w", err)
|
||||||
|
}
|
||||||
|
httpReq.Header.Set("Content-Type", "application/json")
|
||||||
|
httpReq.Header.Set("Authorization", "Bearer "+signedToken)
|
||||||
|
|
||||||
|
client := &http.Client{Timeout: 15 * time.Second}
|
||||||
|
resp, err := client.Do(httpReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to send transaction status request: %w", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, fmt.Errorf("transaction status request failed with status code: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Decode response
|
||||||
|
var responseBody map[string]any
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&responseBody); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to decode transaction status response: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return responseBody, nil
|
return responseBody, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,13 @@ import (
|
||||||
// @Tags SantimPay
|
// @Tags SantimPay
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param request body domain.GeneratePaymentURLInput true "SantimPay payment request payload"
|
// @Param request body domain.GeneratePaymentURLRequest true "SantimPay payment request payload"
|
||||||
// @Success 200 {object} domain.Response
|
// @Success 200 {object} domain.Response
|
||||||
// @Failure 400 {object} domain.ErrorResponse
|
// @Failure 400 {object} domain.ErrorResponse
|
||||||
// @Failure 500 {object} domain.ErrorResponse
|
// @Failure 500 {object} domain.ErrorResponse
|
||||||
// @Router /api/v1/santimpay/payment [post]
|
// @Router /api/v1/santimpay/payment [post]
|
||||||
func (h *Handler) CreateSantimPayPaymentHandler(c *fiber.Ctx) error {
|
func (h *Handler) InititateSantimPayPaymentHandler(c *fiber.Ctx) error {
|
||||||
var req domain.GeneratePaymentURLInput
|
var req domain.GeneratePaymentURLRequest
|
||||||
if err := c.BodyParser(&req); err != nil {
|
if err := c.BodyParser(&req); err != nil {
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||||
Error: err.Error(),
|
Error: err.Error(),
|
||||||
|
|
@ -26,7 +26,7 @@ func (h *Handler) CreateSantimPayPaymentHandler(c *fiber.Ctx) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
paymentURL, err := h.santimpaySvc.GeneratePaymentURL(req)
|
paymentURL, err := h.santimpaySvc.InitiatePayment(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
|
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
|
||||||
Error: err.Error(),
|
Error: err.Error(),
|
||||||
|
|
@ -41,3 +41,192 @@ func (h *Handler) CreateSantimPayPaymentHandler(c *fiber.Ctx) error {
|
||||||
StatusCode: fiber.StatusOK,
|
StatusCode: fiber.StatusOK,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcessSantimPayCallbackHandler handles incoming SantimPay payment callbacks.
|
||||||
|
//
|
||||||
|
// @Summary Process SantimPay Payment Callback
|
||||||
|
// @Description Processes a callback from SantimPay, updates transfer status, and credits user wallet if payment was successful.
|
||||||
|
// @Tags SantimPay
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param request body domain.SantimPayCallbackPayload true "SantimPay callback payload"
|
||||||
|
// @Success 200 {object} domain.Response
|
||||||
|
// @Failure 400 {object} domain.ErrorResponse
|
||||||
|
// @Failure 500 {object} domain.ErrorResponse
|
||||||
|
// @Router /api/v1/santimpay/callback [post]
|
||||||
|
func (h *Handler) ProcessSantimPayCallbackHandler(c *fiber.Ctx) error {
|
||||||
|
var payload domain.SantimPayCallbackPayload
|
||||||
|
if err := c.BodyParser(&payload); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||||
|
Error: err.Error(),
|
||||||
|
Message: "Invalid callback payload",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := h.santimpaySvc.ProcessCallback(c.Context(), payload); err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
|
||||||
|
Error: err.Error(),
|
||||||
|
Message: "Failed to process SantimPay callback",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||||
|
Message: "SantimPay callback processed successfully",
|
||||||
|
Data: nil,
|
||||||
|
Success: true,
|
||||||
|
StatusCode: fiber.StatusOK,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProcessSantimPayDirectPaymentHandler initializes a direct payment session with SantimPay.
|
||||||
|
//
|
||||||
|
// @Summary Process SantimPay Direct Payment
|
||||||
|
// @Description Initiates a direct payment request with SantimPay and returns the response.
|
||||||
|
// @Tags SantimPay
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param request body domain.GeneratePaymentURLRequest true "SantimPay direct payment request payload"
|
||||||
|
// @Success 200 {object} domain.Response
|
||||||
|
// @Failure 400 {object} domain.ErrorResponse
|
||||||
|
// @Failure 500 {object} domain.ErrorResponse
|
||||||
|
// @Router /api/v1/santimpay/direct-payment [post]
|
||||||
|
func (h *Handler) ProcessSantimPayDirectPaymentHandler(c *fiber.Ctx) error {
|
||||||
|
var req domain.GeneratePaymentURLRequest
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||||
|
Error: err.Error(),
|
||||||
|
Message: "Invalid direct payment request payload",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := h.santimpaySvc.ProcessDirectPayment(c.Context(), req)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
|
||||||
|
Error: err.Error(),
|
||||||
|
Message: "Failed to process SantimPay direct payment",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||||
|
Message: "SantimPay direct payment processed successfully",
|
||||||
|
Data: response,
|
||||||
|
Success: true,
|
||||||
|
StatusCode: fiber.StatusOK,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSantimPayB2CPartnersHandler retrieves all available SantimPay B2C payout partners.
|
||||||
|
//
|
||||||
|
// @Summary Get SantimPay B2C Partners
|
||||||
|
// @Description Fetches a list of available B2C payout partners (e.g., Telebirr, Mpesa, Banks) from SantimPay.
|
||||||
|
// @Tags SantimPay
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} domain.Response
|
||||||
|
// @Failure 500 {object} domain.ErrorResponse
|
||||||
|
// @Router /api/v1/santimpay/b2c/partners [get]
|
||||||
|
func (h *Handler) GetSantimPayB2CPartnersHandler(c *fiber.Ctx) error {
|
||||||
|
partners, err := h.santimpaySvc.GetB2CPartners(c.Context())
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
|
||||||
|
Error: err.Error(),
|
||||||
|
Message: "Failed to fetch SantimPay B2C partners",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||||
|
Message: "SantimPay B2C partners retrieved successfully",
|
||||||
|
Data: partners,
|
||||||
|
Success: true,
|
||||||
|
StatusCode: fiber.StatusOK,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProcessSantimPayB2CWithdrawalHandler processes a B2C (Withdrawal) transaction with SantimPay.
|
||||||
|
//
|
||||||
|
// @Summary Process SantimPay B2C Withdrawal
|
||||||
|
// @Description Initiates a B2C withdrawal request with SantimPay and returns the response.
|
||||||
|
// @Tags SantimPay
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param request body domain.GeneratePaymentURLRequest true "SantimPay B2C withdrawal request payload"
|
||||||
|
// @Success 200 {object} domain.Response
|
||||||
|
// @Failure 400 {object} domain.ErrorResponse
|
||||||
|
// @Failure 500 {object} domain.ErrorResponse
|
||||||
|
// @Router /api/v1/santimpay/b2c-withdrawal [post]
|
||||||
|
func (h *Handler) ProcessSantimPayB2CWithdrawalHandler(c *fiber.Ctx) error {
|
||||||
|
var req domain.GeneratePaymentURLRequest
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||||
|
Error: err.Error(),
|
||||||
|
Message: "Invalid B2C withdrawal request payload",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract userId from context/session (adapt based on your auth flow)
|
||||||
|
userId, ok := c.Locals("userId").(int64)
|
||||||
|
if !ok {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||||
|
Error: "missing userId in context",
|
||||||
|
Message: "Could not process withdrawal without user ID",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := h.santimpaySvc.ProcessB2CWithdrawal(c.Context(), req, userId)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
|
||||||
|
Error: err.Error(),
|
||||||
|
Message: "Failed to process SantimPay B2C withdrawal",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||||
|
Message: "SantimPay B2C withdrawal processed successfully",
|
||||||
|
Data: response,
|
||||||
|
Success: true,
|
||||||
|
StatusCode: fiber.StatusOK,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckSantimPayTransactionStatusHandler checks the status of a SantimPay transaction.
|
||||||
|
//
|
||||||
|
// @Summary Check SantimPay Transaction Status
|
||||||
|
// @Description Retrieves the real-time status of a transaction from SantimPay.
|
||||||
|
// @Tags SantimPay
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param request body domain.TransactionStatusRequest true "Transaction status request payload"
|
||||||
|
// @Success 200 {object} domain.Response
|
||||||
|
// @Failure 400 {object} domain.ErrorResponse
|
||||||
|
// @Failure 500 {object} domain.ErrorResponse
|
||||||
|
// @Router /api/v1/santimpay/transaction-status [post]
|
||||||
|
func (h *Handler) CheckSantimPayTransactionStatusHandler(c *fiber.Ctx) error {
|
||||||
|
var req domain.TransactionStatusRequest
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
|
||||||
|
Error: err.Error(),
|
||||||
|
Message: "Invalid transaction status request payload",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional: extract fullParams from request, default to true if not provided
|
||||||
|
fullParams := true
|
||||||
|
if req.FullParams == nil {
|
||||||
|
req.FullParams = &fullParams
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := h.santimpaySvc.CheckTransactionStatus(c.Context(), req)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
|
||||||
|
Error: err.Error(),
|
||||||
|
Message: "Failed to check SantimPay transaction status",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||||
|
Message: "SantimPay transaction status retrieved successfully",
|
||||||
|
Data: response,
|
||||||
|
Success: true,
|
||||||
|
StatusCode: fiber.StatusOK,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import (
|
||||||
// @Tags Telebirr
|
// @Tags Telebirr
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param request body domain.GeneratePaymentURLInput true "Telebirr payment request payload"
|
// @Param request body domain.GeneratePaymentURLRequest true "Telebirr payment request payload"
|
||||||
// @Success 200 {object} domain.Response
|
// @Success 200 {object} domain.Response
|
||||||
// @Failure 400 {object} domain.ErrorResponse
|
// @Failure 400 {object} domain.ErrorResponse
|
||||||
// @Failure 500 {object} domain.ErrorResponse
|
// @Failure 500 {object} domain.ErrorResponse
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,13 @@ func (a *App) initAppRoutes() {
|
||||||
groupV1.Post("/telebirr/callback", h.HandleTelebirrCallback)
|
groupV1.Post("/telebirr/callback", h.HandleTelebirrCallback)
|
||||||
|
|
||||||
//Santimpay
|
//Santimpay
|
||||||
groupV1.Post("/santimpay/init-payment", h.CreateSantimPayPaymentHandler)
|
groupV1.Post("/santimpay/init-payment", a.authMiddleware, h.InititateSantimPayPaymentHandler)
|
||||||
|
groupV1.Post("/santimpay/callback", h.ProcessSantimPayCallbackHandler)
|
||||||
|
groupV1.Post("/santimpay/direct-payment", a.authMiddleware, h.ProcessSantimPayDirectPaymentHandler)
|
||||||
|
groupV1.Get("/santimpay/b2c/partners", h.GetSantimPayB2CPartnersHandler)
|
||||||
|
groupV1.Post("/santimpay/b2c/withdraw", a.authMiddleware, h.ProcessSantimPayB2CWithdrawalHandler)
|
||||||
|
groupV1.Post("/santimpay/transaction/verify", a.authMiddleware, h.CheckSantimPayTransactionStatusHandler)
|
||||||
|
|
||||||
// groupV1.Post("/arifpay/b2c/transfer", a.authMiddleware, h.B2CTransferHandler)
|
// groupV1.Post("/arifpay/b2c/transfer", a.authMiddleware, h.B2CTransferHandler)
|
||||||
// groupV1.Post("/arifpay/transaction-id/verify-transaction", a.authMiddleware, h.ArifpayVerifyByTransactionIDHandler)
|
// groupV1.Post("/arifpay/transaction-id/verify-transaction", a.authMiddleware, h.ArifpayVerifyByTransactionIDHandler)
|
||||||
// groupV1.Get("/arifpay/session-id/verify-transaction/:session_id", a.authMiddleware, h.ArifpayVerifyBySessionIDHandler)
|
// groupV1.Get("/arifpay/session-id/verify-transaction/:session_id", a.authMiddleware, h.ArifpayVerifyBySessionIDHandler)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user