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)
|
||||
aleaService := alea.NewAleaPlayService(vitualGameRepo, *walletSvc, cfg, logger)
|
||||
veliCLient := veli.NewClient(cfg, walletSvc)
|
||||
veliVirtualGameService := veli.New(veliCLient, walletSvc,cfg)
|
||||
veliVirtualGameService := veli.New(veliCLient, walletSvc, cfg)
|
||||
recommendationSvc := recommendation.NewService(recommendationRepo)
|
||||
chapaClient := chapa.NewClient(cfg.CHAPA_BASE_URL, cfg.CHAPA_SECRET_KEY)
|
||||
|
||||
|
|
@ -239,7 +239,7 @@ func main() {
|
|||
|
||||
santimpayClient := santimpay.NewSantimPayClient(cfg)
|
||||
|
||||
santimpaySvc := santimpay.NewSantimPayService(santimpayClient, cfg, transferStore)
|
||||
santimpaySvc := santimpay.NewSantimPayService(santimpayClient, cfg, transferStore, walletSvc)
|
||||
telebirrSvc := telebirr.NewTelebirrService(cfg, transferStore, walletSvc)
|
||||
|
||||
// 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": {
|
||||
"post": {
|
||||
"description": "Generates a payment URL using SantimPay and returns it to the client.",
|
||||
|
|
@ -4331,7 +4498,53 @@ const docTemplate = `{
|
|||
"in": "body",
|
||||
"required": true,
|
||||
"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",
|
||||
"required": true,
|
||||
"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": {
|
||||
"post": {
|
||||
"description": "Retrieves the list of VeliGames providers",
|
||||
|
|
@ -8270,10 +8541,6 @@ const docTemplate = `{
|
|||
"domain.GamingActivityRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"brandId": {
|
||||
"description": "Required",
|
||||
"type": "string"
|
||||
},
|
||||
"currencies": {
|
||||
"description": "Optional",
|
||||
"type": "array",
|
||||
|
|
@ -8335,20 +8602,20 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.GeneratePaymentURLInput": {
|
||||
"domain.GeneratePaymentURLRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"paymentMethod": {
|
||||
"type": "string"
|
||||
},
|
||||
"paymentReason": {
|
||||
"type": "string"
|
||||
},
|
||||
"phoneNumber": {
|
||||
"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": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -8919,6 +9288,68 @@ const docTemplate = `{
|
|||
"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": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -9383,6 +9814,17 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.TransactionStatusRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"fullParams": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.UpcomingEvent": {
|
||||
"type": "object",
|
||||
"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": {
|
||||
"post": {
|
||||
"description": "Generates a payment URL using SantimPay and returns it to the client.",
|
||||
|
|
@ -4323,7 +4490,53 @@
|
|||
"in": "body",
|
||||
"required": true,
|
||||
"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",
|
||||
"required": true,
|
||||
"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": {
|
||||
"post": {
|
||||
"description": "Retrieves the list of VeliGames providers",
|
||||
|
|
@ -8262,10 +8533,6 @@
|
|||
"domain.GamingActivityRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"brandId": {
|
||||
"description": "Required",
|
||||
"type": "string"
|
||||
},
|
||||
"currencies": {
|
||||
"description": "Optional",
|
||||
"type": "array",
|
||||
|
|
@ -8327,20 +8594,20 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.GeneratePaymentURLInput": {
|
||||
"domain.GeneratePaymentURLRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"paymentMethod": {
|
||||
"type": "string"
|
||||
},
|
||||
"paymentReason": {
|
||||
"type": "string"
|
||||
},
|
||||
"phoneNumber": {
|
||||
"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": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -8911,6 +9280,68 @@
|
|||
"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": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -9375,6 +9806,17 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.TransactionStatusRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"fullParams": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.UpcomingEvent": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
|
|||
|
|
@ -770,9 +770,6 @@ definitions:
|
|||
type: object
|
||||
domain.GamingActivityRequest:
|
||||
properties:
|
||||
brandId:
|
||||
description: Required
|
||||
type: string
|
||||
currencies:
|
||||
description: Optional
|
||||
items:
|
||||
|
|
@ -816,16 +813,16 @@ definitions:
|
|||
meta:
|
||||
$ref: '#/definitions/domain.PaginationMeta'
|
||||
type: object
|
||||
domain.GeneratePaymentURLInput:
|
||||
domain.GeneratePaymentURLRequest:
|
||||
properties:
|
||||
amount:
|
||||
type: integer
|
||||
id:
|
||||
paymentMethod:
|
||||
type: string
|
||||
paymentReason:
|
||||
type: string
|
||||
phoneNumber:
|
||||
type: string
|
||||
reason:
|
||||
type: string
|
||||
type: object
|
||||
domain.GetCompanyRes:
|
||||
properties:
|
||||
|
|
@ -863,6 +860,73 @@ definitions:
|
|||
example: 1
|
||||
type: integer
|
||||
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:
|
||||
properties:
|
||||
data:
|
||||
|
|
@ -1217,6 +1281,47 @@ definitions:
|
|||
- RoleBranchManager
|
||||
- RoleCustomer
|
||||
- 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:
|
||||
properties:
|
||||
account_name:
|
||||
|
|
@ -1543,6 +1648,13 @@ definitions:
|
|||
example: 4.22
|
||||
type: number
|
||||
type: object
|
||||
domain.TransactionStatusRequest:
|
||||
properties:
|
||||
fullParams:
|
||||
type: boolean
|
||||
id:
|
||||
type: string
|
||||
type: object
|
||||
domain.UpcomingEvent:
|
||||
properties:
|
||||
away_kit_image:
|
||||
|
|
@ -5200,6 +5312,119 @@ paths:
|
|||
summary: Get results for an event
|
||||
tags:
|
||||
- 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:
|
||||
post:
|
||||
consumes:
|
||||
|
|
@ -5211,7 +5436,7 @@ paths:
|
|||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/domain.GeneratePaymentURLInput'
|
||||
$ref: '#/definitions/domain.GeneratePaymentURLRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
|
|
@ -5230,6 +5455,36 @@ paths:
|
|||
summary: Create SantimPay Payment Session
|
||||
tags:
|
||||
- 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:
|
||||
get:
|
||||
consumes:
|
||||
|
|
@ -5936,7 +6191,7 @@ paths:
|
|||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/domain.GeneratePaymentURLInput'
|
||||
$ref: '#/definitions/domain.GeneratePaymentURLRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
|
|
@ -6593,6 +6848,42 @@ paths:
|
|||
summary: Get Veli Gaming Activity
|
||||
tags:
|
||||
- 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:
|
||||
post:
|
||||
consumes:
|
||||
|
|
|
|||
|
|
@ -83,8 +83,11 @@ type ARIFPAYConfig struct {
|
|||
|
||||
type SANTIMPAYConfig struct {
|
||||
SecretKey string `mapstructure:"secret_key"`
|
||||
MerchantID string `mapstructure:"merchant_id"`
|
||||
MerchantID string `mapstructure:"merchantId"`
|
||||
BaseURL string `mapstructure:"base_url"`
|
||||
NotifyURL string `mapstructure:"notifyUrl"`
|
||||
CancelUrl string `mapstructure:"cancelUrl"`
|
||||
SuccessUrl string `mapstructure:"successUrl"`
|
||||
}
|
||||
|
||||
type TELEBIRRConfig struct {
|
||||
|
|
@ -254,7 +257,9 @@ func (c *Config) loadEnv() error {
|
|||
|
||||
c.SANTIMPAY.SecretKey = os.Getenv("SANTIMPAY_SECRET_KEY")
|
||||
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
|
||||
aleaEnabled := os.Getenv("ALEA_ENABLED")
|
||||
|
|
|
|||
|
|
@ -1,17 +1,13 @@
|
|||
package domain
|
||||
|
||||
type GeneratePaymentURLInput struct {
|
||||
ID string
|
||||
Amount int
|
||||
Reason string
|
||||
PhoneNumber string
|
||||
// SuccessRedirectURL string
|
||||
// FailureRedirectURL string
|
||||
// CancelRedirectURL string
|
||||
// NotifyURL string
|
||||
type GeneratePaymentURLRequest struct {
|
||||
Amount int `json:"amount"`
|
||||
Reason string `json:"paymentReason"`
|
||||
PhoneNumber string `json:"phoneNumber"`
|
||||
PaymentMethod string `json:"paymentMethod,omitempty"`
|
||||
}
|
||||
|
||||
type InitiatePaymentPayload struct {
|
||||
type InitiatePaymentRequest struct {
|
||||
ID string `json:"id"`
|
||||
Amount int `json:"amount"`
|
||||
Reason string `json:"paymentReason"`
|
||||
|
|
@ -22,4 +18,64 @@ type InitiatePaymentPayload struct {
|
|||
NotifyURL string `json:"notifyUrl"`
|
||||
CancelRedirectURL string `json:"cancelRedirectUrl"`
|
||||
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"
|
||||
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
)
|
||||
|
||||
type SantimPayClient interface {
|
||||
GenerateSignedToken(amount int, reason string) (string, error)
|
||||
GenerateSignedToken(payload domain.SantimTokenPayload) (string, error)
|
||||
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()
|
||||
|
||||
claims := jwt.MapClaims{
|
||||
"amount": amount,
|
||||
"paymentReason": reason,
|
||||
"merchantId": c.cfg.SANTIMPAY.MerchantID,
|
||||
"generated": now,
|
||||
"amount": payload.Amount,
|
||||
"paymentReason": payload.Reason,
|
||||
"merchantId": c.cfg.SANTIMPAY.MerchantID,
|
||||
"generated": now,
|
||||
}
|
||||
|
||||
// Optional fields
|
||||
if payload.PaymentMethod != "" {
|
||||
claims["paymentMethod"] = payload.PaymentMethod
|
||||
}
|
||||
if payload.PhoneNumber != "" {
|
||||
claims["phoneNumber"] = payload.PhoneNumber
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodES256, claims)
|
||||
|
||||
privateKey, err := jwt.ParseECPrivateKeyFromPEM([]byte(c.cfg.SANTIMPAY.SecretKey))
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
func (c *santimClient) CheckTransactionStatus(id string) {
|
||||
// optional async checker — can log or poll transaction status
|
||||
fmt.Println("Checking transaction status for:", id)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
|
|
@ -14,42 +16,51 @@ import (
|
|||
)
|
||||
|
||||
// type SantimPayService interface {
|
||||
// GeneratePaymentURL(input domain.GeneratePaymentURLInput) (map[string]string, error)
|
||||
// GeneratePaymentURL(req domain.GeneratePaymentURLreq) (map[string]string, error)
|
||||
// }
|
||||
|
||||
type SantimPayService struct {
|
||||
client SantimPayClient
|
||||
cfg *config.Config
|
||||
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{
|
||||
client: client,
|
||||
cfg: cfg,
|
||||
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()
|
||||
|
||||
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 {
|
||||
return nil, fmt.Errorf("token generation failed: %w", err)
|
||||
}
|
||||
|
||||
payload := domain.InitiatePaymentPayload{
|
||||
// 2. Prepare payload (without token in body)
|
||||
payload := domain.InitiatePaymentRequest{
|
||||
ID: paymentID,
|
||||
Amount: input.Amount,
|
||||
Reason: input.Reason,
|
||||
Amount: req.Amount,
|
||||
Reason: req.Reason,
|
||||
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,
|
||||
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)
|
||||
|
|
@ -57,7 +68,16 @@ func (s *SantimPayService) GeneratePaymentURL(input domain.GeneratePaymentURLInp
|
|||
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 {
|
||||
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)
|
||||
}
|
||||
|
||||
// Save transfer
|
||||
// 4. Save transfer
|
||||
transfer := domain.CreateTransfer{
|
||||
Amount: domain.Currency(input.Amount),
|
||||
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)
|
||||
}
|
||||
|
||||
// Optionally check transaction status in a goroutine
|
||||
go s.client.CheckTransactionStatus(paymentID)
|
||||
// 5. Optionally check transaction status asynchronously
|
||||
// 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ import (
|
|||
// @Tags SantimPay
|
||||
// @Accept 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
|
||||
// @Failure 400 {object} domain.ErrorResponse
|
||||
// @Failure 500 {object} domain.ErrorResponse
|
||||
// @Router /api/v1/santimpay/payment [post]
|
||||
func (h *Handler) CreateSantimPayPaymentHandler(c *fiber.Ctx) error {
|
||||
var req domain.GeneratePaymentURLInput
|
||||
func (h *Handler) InititateSantimPayPaymentHandler(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(),
|
||||
|
|
@ -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 {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
|
||||
Error: err.Error(),
|
||||
|
|
@ -41,3 +41,192 @@ func (h *Handler) CreateSantimPayPaymentHandler(c *fiber.Ctx) error {
|
|||
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
|
||||
// @Accept 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
|
||||
// @Failure 400 {object} domain.ErrorResponse
|
||||
// @Failure 500 {object} domain.ErrorResponse
|
||||
|
|
|
|||
|
|
@ -127,7 +127,13 @@ func (a *App) initAppRoutes() {
|
|||
groupV1.Post("/telebirr/callback", h.HandleTelebirrCallback)
|
||||
|
||||
//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/transaction-id/verify-transaction", a.authMiddleware, h.ArifpayVerifyByTransactionIDHandler)
|
||||
// groupV1.Get("/arifpay/session-id/verify-transaction/:session_id", a.authMiddleware, h.ArifpayVerifyBySessionIDHandler)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user