createTransaction+createTransfer fix
This commit is contained in:
parent
eb8abfc963
commit
75d469be8c
|
|
@ -109,11 +109,15 @@ func main() {
|
|||
logger,
|
||||
)
|
||||
recommendationSvc := recommendation.NewService(recommendationRepo)
|
||||
chapaClient := chapa.NewClient(cfg.CHAPA_BASE_URL, cfg.CHAPA_SECRET_KEY)
|
||||
|
||||
chapaSvc := chapa.NewService(
|
||||
transaction.TransactionStore(store),
|
||||
wallet.WalletStore(store),
|
||||
user.UserStore(store),
|
||||
referalSvc,
|
||||
branch.BranchStore(store),
|
||||
chapaClient,
|
||||
store,
|
||||
)
|
||||
|
||||
|
|
|
|||
259
docs/docs.go
259
docs/docs.go
|
|
@ -361,6 +361,63 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/chapa/payments/deposit": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Deposits money into user wallet from user account using Chapa",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Chapa"
|
||||
],
|
||||
"summary": "Deposit money into user wallet using Chapa",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Deposit request payload",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.ChapaDepositRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.ChapaPaymentUrlResponseWrapper"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal server error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/chapa/payments/initialize": {
|
||||
"post": {
|
||||
"description": "Initiate a payment through Chapa",
|
||||
|
|
@ -395,6 +452,39 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/chapa/payments/verify": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Chapa"
|
||||
],
|
||||
"summary": "Verifies Chapa webhook transaction",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Webhook Payload",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.ChapaTransactionType"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/chapa/payments/verify/{tx_ref}": {
|
||||
"get": {
|
||||
"description": "Verify the transaction status from Chapa using tx_ref",
|
||||
|
|
@ -427,6 +517,76 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/chapa/payments/withdraw": {
|
||||
"post": {
|
||||
"description": "Initiates a withdrawal transaction using Chapa for the authenticated user.",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Chapa"
|
||||
],
|
||||
"summary": "Withdraw using Chapa",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Chapa Withdraw Request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.ChapaWithdrawRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Withdrawal requested successfully",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Unprocessable Entity",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/chapa/transfers": {
|
||||
"post": {
|
||||
"description": "Initiate a transfer request via Chapa",
|
||||
|
|
@ -4413,6 +4573,46 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.ChapaDepositRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"type": "integer"
|
||||
},
|
||||
"branch_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"currency": {
|
||||
"type": "string"
|
||||
},
|
||||
"phone_number": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.ChapaPaymentUrlResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"payment_url": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.ChapaPaymentUrlResponseWrapper": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"status_code": {
|
||||
"type": "integer"
|
||||
},
|
||||
"success": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.ChapaSupportedBank": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -4480,6 +4680,44 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.ChapaTransactionType": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.ChapaWithdrawRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"account_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"account_number": {
|
||||
"type": "string"
|
||||
},
|
||||
"amount": {
|
||||
"type": "integer"
|
||||
},
|
||||
"bank_code": {
|
||||
"type": "string"
|
||||
},
|
||||
"beneficiary_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"branch_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"currency": {
|
||||
"type": "string"
|
||||
},
|
||||
"wallet_id": {
|
||||
"description": "add this",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.CreateBetOutcomeReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -4561,7 +4799,7 @@ const docTemplate = `{
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"type": "string"
|
||||
"type": "integer"
|
||||
},
|
||||
"callback_url": {
|
||||
"type": "string"
|
||||
|
|
@ -4832,6 +5070,21 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.Response": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"status_code": {
|
||||
"type": "integer"
|
||||
},
|
||||
"success": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.Role": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
|
@ -5041,6 +5294,10 @@ const docTemplate = `{
|
|||
"description": "Match or event name",
|
||||
"type": "string"
|
||||
},
|
||||
"source": {
|
||||
"description": "bet api provider (bet365, betfair)",
|
||||
"type": "string"
|
||||
},
|
||||
"sportID": {
|
||||
"description": "Sport ID",
|
||||
"type": "string"
|
||||
|
|
|
|||
|
|
@ -353,6 +353,63 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/chapa/payments/deposit": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Deposits money into user wallet from user account using Chapa",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Chapa"
|
||||
],
|
||||
"summary": "Deposit money into user wallet using Chapa",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Deposit request payload",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.ChapaDepositRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.ChapaPaymentUrlResponseWrapper"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal server error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/chapa/payments/initialize": {
|
||||
"post": {
|
||||
"description": "Initiate a payment through Chapa",
|
||||
|
|
@ -387,6 +444,39 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/chapa/payments/verify": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Chapa"
|
||||
],
|
||||
"summary": "Verifies Chapa webhook transaction",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Webhook Payload",
|
||||
"name": "payload",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.ChapaTransactionType"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/chapa/payments/verify/{tx_ref}": {
|
||||
"get": {
|
||||
"description": "Verify the transaction status from Chapa using tx_ref",
|
||||
|
|
@ -419,6 +509,76 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/chapa/payments/withdraw": {
|
||||
"post": {
|
||||
"description": "Initiates a withdrawal transaction using Chapa for the authenticated user.",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Chapa"
|
||||
],
|
||||
"summary": "Withdraw using Chapa",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Chapa Withdraw Request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.ChapaWithdrawRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Withdrawal requested successfully",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Unprocessable Entity",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/domain.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/chapa/transfers": {
|
||||
"post": {
|
||||
"description": "Initiate a transfer request via Chapa",
|
||||
|
|
@ -4405,6 +4565,46 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.ChapaDepositRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"type": "integer"
|
||||
},
|
||||
"branch_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"currency": {
|
||||
"type": "string"
|
||||
},
|
||||
"phone_number": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.ChapaPaymentUrlResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"payment_url": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.ChapaPaymentUrlResponseWrapper": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"status_code": {
|
||||
"type": "integer"
|
||||
},
|
||||
"success": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.ChapaSupportedBank": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -4472,6 +4672,44 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.ChapaTransactionType": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.ChapaWithdrawRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"account_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"account_number": {
|
||||
"type": "string"
|
||||
},
|
||||
"amount": {
|
||||
"type": "integer"
|
||||
},
|
||||
"bank_code": {
|
||||
"type": "string"
|
||||
},
|
||||
"beneficiary_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"branch_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"currency": {
|
||||
"type": "string"
|
||||
},
|
||||
"wallet_id": {
|
||||
"description": "add this",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.CreateBetOutcomeReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -4553,7 +4791,7 @@
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"type": "string"
|
||||
"type": "integer"
|
||||
},
|
||||
"callback_url": {
|
||||
"type": "string"
|
||||
|
|
@ -4824,6 +5062,21 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"domain.Response": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"status_code": {
|
||||
"type": "integer"
|
||||
},
|
||||
"success": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain.Role": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
|
@ -5033,6 +5286,10 @@
|
|||
"description": "Match or event name",
|
||||
"type": "string"
|
||||
},
|
||||
"source": {
|
||||
"description": "bet api provider (bet365, betfair)",
|
||||
"type": "string"
|
||||
},
|
||||
"sportID": {
|
||||
"description": "Sport ID",
|
||||
"type": "string"
|
||||
|
|
|
|||
|
|
@ -124,6 +124,32 @@ definitions:
|
|||
example: 2
|
||||
type: integer
|
||||
type: object
|
||||
domain.ChapaDepositRequest:
|
||||
properties:
|
||||
amount:
|
||||
type: integer
|
||||
branch_id:
|
||||
type: integer
|
||||
currency:
|
||||
type: string
|
||||
phone_number:
|
||||
type: string
|
||||
type: object
|
||||
domain.ChapaPaymentUrlResponse:
|
||||
properties:
|
||||
payment_url:
|
||||
type: string
|
||||
type: object
|
||||
domain.ChapaPaymentUrlResponseWrapper:
|
||||
properties:
|
||||
data: {}
|
||||
message:
|
||||
type: string
|
||||
status_code:
|
||||
type: integer
|
||||
success:
|
||||
type: boolean
|
||||
type: object
|
||||
domain.ChapaSupportedBank:
|
||||
properties:
|
||||
acct_length:
|
||||
|
|
@ -168,6 +194,31 @@ definitions:
|
|||
message:
|
||||
type: string
|
||||
type: object
|
||||
domain.ChapaTransactionType:
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
domain.ChapaWithdrawRequest:
|
||||
properties:
|
||||
account_name:
|
||||
type: string
|
||||
account_number:
|
||||
type: string
|
||||
amount:
|
||||
type: integer
|
||||
bank_code:
|
||||
type: string
|
||||
beneficiary_name:
|
||||
type: string
|
||||
branch_id:
|
||||
type: integer
|
||||
currency:
|
||||
type: string
|
||||
wallet_id:
|
||||
description: add this
|
||||
type: integer
|
||||
type: object
|
||||
domain.CreateBetOutcomeReq:
|
||||
properties:
|
||||
event_id:
|
||||
|
|
@ -222,7 +273,7 @@ definitions:
|
|||
domain.InitPaymentRequest:
|
||||
properties:
|
||||
amount:
|
||||
type: string
|
||||
type: integer
|
||||
callback_url:
|
||||
type: string
|
||||
currency:
|
||||
|
|
@ -408,6 +459,16 @@ definitions:
|
|||
totalRewardEarned:
|
||||
type: number
|
||||
type: object
|
||||
domain.Response:
|
||||
properties:
|
||||
data: {}
|
||||
message:
|
||||
type: string
|
||||
status_code:
|
||||
type: integer
|
||||
success:
|
||||
type: boolean
|
||||
type: object
|
||||
domain.Role:
|
||||
enum:
|
||||
- super_admin
|
||||
|
|
@ -555,6 +616,9 @@ definitions:
|
|||
matchName:
|
||||
description: Match or event name
|
||||
type: string
|
||||
source:
|
||||
description: bet api provider (bet365, betfair)
|
||||
type: string
|
||||
sportID:
|
||||
description: Sport ID
|
||||
type: string
|
||||
|
|
@ -1721,6 +1785,42 @@ paths:
|
|||
summary: Receive Chapa webhook
|
||||
tags:
|
||||
- Chapa
|
||||
/api/v1/chapa/payments/deposit:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Deposits money into user wallet from user account using Chapa
|
||||
parameters:
|
||||
- description: Deposit request payload
|
||||
in: body
|
||||
name: payload
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/domain.ChapaDepositRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/domain.ChapaPaymentUrlResponseWrapper'
|
||||
"400":
|
||||
description: Invalid request
|
||||
schema:
|
||||
$ref: '#/definitions/domain.Response'
|
||||
"422":
|
||||
description: Validation error
|
||||
schema:
|
||||
$ref: '#/definitions/domain.Response'
|
||||
"500":
|
||||
description: Internal server error
|
||||
schema:
|
||||
$ref: '#/definitions/domain.Response'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Deposit money into user wallet using Chapa
|
||||
tags:
|
||||
- Chapa
|
||||
/api/v1/chapa/payments/initialize:
|
||||
post:
|
||||
consumes:
|
||||
|
|
@ -1743,6 +1843,27 @@ paths:
|
|||
summary: Initialize a payment transaction
|
||||
tags:
|
||||
- Chapa
|
||||
/api/v1/chapa/payments/verify:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
parameters:
|
||||
- description: Webhook Payload
|
||||
in: body
|
||||
name: payload
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/domain.ChapaTransactionType'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/domain.Response'
|
||||
summary: Verifies Chapa webhook transaction
|
||||
tags:
|
||||
- Chapa
|
||||
/api/v1/chapa/payments/verify/{tx_ref}:
|
||||
get:
|
||||
consumes:
|
||||
|
|
@ -1764,6 +1885,50 @@ paths:
|
|||
summary: Verify a payment transaction
|
||||
tags:
|
||||
- Chapa
|
||||
/api/v1/chapa/payments/withdraw:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Initiates a withdrawal transaction using Chapa for the authenticated
|
||||
user.
|
||||
parameters:
|
||||
- description: Chapa Withdraw Request
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/domain.ChapaWithdrawRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: Withdrawal requested successfully
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/domain.Response'
|
||||
- properties:
|
||||
data:
|
||||
type: string
|
||||
type: object
|
||||
"400":
|
||||
description: Invalid request
|
||||
schema:
|
||||
$ref: '#/definitions/domain.Response'
|
||||
"401":
|
||||
description: Unauthorized
|
||||
schema:
|
||||
$ref: '#/definitions/domain.Response'
|
||||
"422":
|
||||
description: Unprocessable Entity
|
||||
schema:
|
||||
$ref: '#/definitions/domain.Response'
|
||||
"500":
|
||||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/domain.Response'
|
||||
summary: Withdraw using Chapa
|
||||
tags:
|
||||
- Chapa
|
||||
/api/v1/chapa/transfers:
|
||||
post:
|
||||
consumes:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
package domain
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
ChapaSecret string
|
||||
|
|
@ -8,7 +11,7 @@ var (
|
|||
)
|
||||
|
||||
type InitPaymentRequest struct {
|
||||
Amount string `json:"amount"`
|
||||
Amount Currency `json:"amount"`
|
||||
Currency string `json:"currency"`
|
||||
Email string `json:"email"`
|
||||
FirstName string `json:"first_name"`
|
||||
|
|
@ -149,3 +152,72 @@ type ChapaWebHookPayment struct {
|
|||
} `json:"customization"`
|
||||
Meta string `json:"meta"`
|
||||
}
|
||||
|
||||
type ChapaWithdrawRequest struct {
|
||||
WalletID int64 `json:"wallet_id"` // add this
|
||||
AccountName string `json:"account_name"`
|
||||
AccountNumber string `json:"account_number"`
|
||||
Amount int64 `json:"amount"`
|
||||
Currency string `json:"currency"`
|
||||
BeneficiaryName string `json:"beneficiary_name"`
|
||||
BankCode string `json:"bank_code"`
|
||||
BranchID int64 `json:"branch_id"`
|
||||
}
|
||||
|
||||
type ChapaTransferPayload struct {
|
||||
AccountName string
|
||||
AccountNumber string
|
||||
Amount string
|
||||
Currency string
|
||||
BeneficiaryName string
|
||||
TxRef string
|
||||
Reference string
|
||||
BankCode string
|
||||
}
|
||||
|
||||
type ChapaDepositRequest struct {
|
||||
Amount Currency `json:"amount"`
|
||||
PhoneNumber string `json:"phone_number"`
|
||||
Currency string `json:"currency"`
|
||||
BranchID int64 `json:"branch_id"`
|
||||
}
|
||||
|
||||
func (r ChapaDepositRequest) Validate() error {
|
||||
if r.Amount <= 0 {
|
||||
return errors.New("amount must be greater than zero")
|
||||
}
|
||||
if r.Currency == "" {
|
||||
return errors.New("currency is required")
|
||||
}
|
||||
if r.PhoneNumber == "" {
|
||||
return errors.New("phone number is required")
|
||||
}
|
||||
if r.BranchID == 0 {
|
||||
return errors.New("branch ID is required")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type AcceptChapaPaymentRequest struct {
|
||||
Amount string `json:"amount"`
|
||||
Currency string `json:"currency"`
|
||||
Email string `json:"email"`
|
||||
FirstName string `json:"first_name"`
|
||||
LastName string `json:"last_name"`
|
||||
PhoneNumber string `json:"phone_number"`
|
||||
TxRef string `json:"tx_ref"`
|
||||
CallbackUrl string `json:"callback_url"`
|
||||
ReturnUrl string `json:"return_url"`
|
||||
CustomizationTitle string `json:"customization[title]"`
|
||||
CustomizationDescription string `json:"customization[description]"`
|
||||
}
|
||||
|
||||
type ChapaPaymentUrlResponse struct {
|
||||
PaymentURL string `json:"payment_url"`
|
||||
}
|
||||
|
||||
type ChapaPaymentUrlResponseWrapper struct {
|
||||
Data ChapaPaymentUrlResponse `json:"data"`
|
||||
Response
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,11 +48,14 @@ func (m Currency) String() string {
|
|||
return fmt.Sprintf("$%.2f", x)
|
||||
}
|
||||
|
||||
type ResponseWDataFactory[T any] struct {
|
||||
Data T `json:"data"`
|
||||
Response
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
Success bool `json:"success"`
|
||||
StatusCode int `json:"status_code"`
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ type CreateTransaction struct {
|
|||
PaymentOption PaymentOption
|
||||
FullName string
|
||||
PhoneNumber string
|
||||
// Payment Details for bank
|
||||
BankCode string
|
||||
BeneficiaryName string
|
||||
AccountName string
|
||||
|
|
|
|||
98
internal/services/chapa/client.go
Normal file
98
internal/services/chapa/client.go
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
package chapa
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
)
|
||||
|
||||
type ChapaClient interface {
|
||||
IssuePayment(ctx context.Context, payload domain.ChapaTransferPayload) (bool, error)
|
||||
InitPayment(ctx context.Context, req domain.InitPaymentRequest) (string, error)
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
BaseURL string
|
||||
SecretKey string
|
||||
HTTPClient *http.Client
|
||||
}
|
||||
|
||||
func NewClient(baseURL, secretKey string) *Client {
|
||||
return &Client{
|
||||
BaseURL: baseURL,
|
||||
SecretKey: secretKey,
|
||||
HTTPClient: http.DefaultClient,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) IssuePayment(ctx context.Context, payload domain.ChapaTransferPayload) (bool, error) {
|
||||
payloadBytes, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to serialize payload: %w", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", c.BaseURL+"/transfers", bytes.NewBuffer(payloadBytes))
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to create HTTP request: %w", err)
|
||||
}
|
||||
|
||||
req.Header.Set("Authorization", "Bearer "+c.SecretKey)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := c.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("chapa HTTP request failed: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, fmt.Errorf("chapa error: status %d, body: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
// service/chapa_service.go
|
||||
func (c *Client) InitPayment(ctx context.Context, req domain.InitPaymentRequest) (string, error) {
|
||||
payloadBytes, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to serialize payload: %w", err)
|
||||
}
|
||||
|
||||
httpReq, err := http.NewRequestWithContext(ctx, "POST", c.BaseURL+"/transaction/initialize", bytes.NewBuffer(payloadBytes))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create HTTP request: %w", err)
|
||||
}
|
||||
|
||||
httpReq.Header.Set("Authorization", "Bearer "+c.SecretKey)
|
||||
httpReq.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := c.HTTPClient.Do(httpReq)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("chapa HTTP request failed: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
return "", fmt.Errorf("chapa error: status %d, body: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
var response struct {
|
||||
Data struct {
|
||||
CheckoutURL string `json:"checkout_url"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(body, &response); err != nil {
|
||||
return "", fmt.Errorf("failed to parse chapa response: %w", err)
|
||||
}
|
||||
|
||||
return response.Data.CheckoutURL, nil
|
||||
}
|
||||
|
|
@ -9,4 +9,6 @@ import (
|
|||
type ChapaPort interface {
|
||||
HandleChapaTransferWebhook(ctx context.Context, req domain.ChapaWebHookTransfer) error
|
||||
HandleChapaPaymentWebhook(ctx context.Context, req domain.ChapaWebHookPayment) error
|
||||
WithdrawUsingChapa(ctx context.Context, userID int64, req domain.ChapaWithdrawRequest) error
|
||||
DepositUsingChapa(ctx context.Context, userID int64, req domain.ChapaDepositRequest) (string, error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,22 @@ package chapa
|
|||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
// "log/slog"
|
||||
"strconv"
|
||||
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/branch"
|
||||
referralservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/referal"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/transaction"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
|
||||
"github.com/google/uuid"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
|
|
@ -19,6 +26,10 @@ type Service struct {
|
|||
walletStore wallet.WalletStore
|
||||
userStore user.UserStore
|
||||
referralStore referralservice.ReferralStore
|
||||
branchStore branch.BranchStore
|
||||
chapaClient ChapaClient
|
||||
config *config.Config
|
||||
// logger *slog.Logger
|
||||
store *repository.Store
|
||||
}
|
||||
|
||||
|
|
@ -27,6 +38,8 @@ func NewService(
|
|||
walletStore wallet.WalletStore,
|
||||
userStore user.UserStore,
|
||||
referralStore referralservice.ReferralStore,
|
||||
branchStore branch.BranchStore,
|
||||
chapaClient ChapaClient,
|
||||
store *repository.Store,
|
||||
) *Service {
|
||||
return &Service{
|
||||
|
|
@ -34,6 +47,8 @@ func NewService(
|
|||
walletStore: walletStore,
|
||||
userStore: userStore,
|
||||
referralStore: referralStore,
|
||||
branchStore: branchStore,
|
||||
chapaClient: chapaClient,
|
||||
store: store,
|
||||
}
|
||||
}
|
||||
|
|
@ -53,6 +68,9 @@ func (s *Service) HandleChapaTransferWebhook(ctx context.Context, req domain.Cha
|
|||
|
||||
txn, err := s.transactionStore.GetTransactionByID(ctx, referenceID)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return fmt.Errorf("transaction with ID %d not found", referenceID)
|
||||
}
|
||||
return err
|
||||
}
|
||||
if txn.Verified {
|
||||
|
|
@ -93,6 +111,9 @@ func (s *Service) HandleChapaPaymentWebhook(ctx context.Context, req domain.Chap
|
|||
// 2. Fetch transaction
|
||||
txn, err := s.transactionStore.GetTransactionByID(ctx, referenceID)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return fmt.Errorf("transaction with ID %d not found", referenceID)
|
||||
}
|
||||
return err
|
||||
}
|
||||
if txn.Verified {
|
||||
|
|
@ -122,7 +143,7 @@ func (s *Service) HandleChapaPaymentWebhook(ctx context.Context, req domain.Chap
|
|||
}
|
||||
|
||||
// 7. Check & Create Referral
|
||||
stats, err := s.referralStore.GetReferralStats(ctx, string(wallet.UserID))
|
||||
stats, err := s.referralStore.GetReferralStats(ctx, strconv.FormatInt(wallet.UserID, 10))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -135,3 +156,162 @@ func (s *Service) HandleChapaPaymentWebhook(ctx context.Context, req domain.Chap
|
|||
|
||||
return tx.Commit(ctx)
|
||||
}
|
||||
|
||||
func (s *Service) WithdrawUsingChapa(ctx context.Context, userID int64, req domain.ChapaWithdrawRequest) error {
|
||||
_, tx, err := s.store.BeginTx(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
// Get the requesting user
|
||||
user, err := s.userStore.GetUserByID(ctx, userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("user not found: %w", err)
|
||||
}
|
||||
|
||||
branch, err := s.branchStore.GetBranchByID(ctx, req.BranchID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wallets, err := s.walletStore.GetWalletsByUser(ctx, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var targetWallet *domain.Wallet
|
||||
for _, w := range wallets {
|
||||
if w.ID == req.WalletID {
|
||||
targetWallet = &w
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if targetWallet == nil {
|
||||
return fmt.Errorf("no wallet found with the specified ID")
|
||||
}
|
||||
|
||||
if !targetWallet.IsWithdraw || !targetWallet.IsActive {
|
||||
return fmt.Errorf("wallet not eligible for withdrawal")
|
||||
}
|
||||
|
||||
if targetWallet.Balance < domain.Currency(req.Amount) {
|
||||
return fmt.Errorf("insufficient balance")
|
||||
}
|
||||
|
||||
txID := uuid.New().String()
|
||||
|
||||
payload := domain.ChapaTransferPayload{
|
||||
AccountName: req.AccountName,
|
||||
AccountNumber: req.AccountNumber,
|
||||
Amount: strconv.FormatInt(req.Amount, 10),
|
||||
Currency: req.Currency,
|
||||
BeneficiaryName: req.BeneficiaryName,
|
||||
TxRef: txID,
|
||||
Reference: txID,
|
||||
BankCode: req.BankCode,
|
||||
}
|
||||
|
||||
ok, err := s.chapaClient.IssuePayment(ctx, payload)
|
||||
if err != nil || !ok {
|
||||
return fmt.Errorf("chapa transfer failed: %v", err)
|
||||
}
|
||||
|
||||
// Create transaction using user and wallet info
|
||||
_, err = s.transactionStore.CreateTransaction(ctx, domain.CreateTransaction{
|
||||
Amount: domain.Currency(req.Amount),
|
||||
Type: domain.TransactionType(domain.TRANSACTION_CASHOUT),
|
||||
ReferenceNumber: txID,
|
||||
AccountName: req.AccountName,
|
||||
AccountNumber: req.AccountNumber,
|
||||
BankCode: req.BankCode,
|
||||
BeneficiaryName: req.BeneficiaryName,
|
||||
PaymentOption: domain.PaymentOption(domain.BANK),
|
||||
BranchID: req.BranchID,
|
||||
BranchName: branch.Name,
|
||||
BranchLocation: branch.Location,
|
||||
// CashierID: user.ID,
|
||||
// CashierName: user.FullName,
|
||||
FullName: user.FirstName + " " + user.LastName,
|
||||
PhoneNumber: user.PhoneNumber,
|
||||
CompanyID: branch.CompanyID,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create transaction: %w", err)
|
||||
}
|
||||
|
||||
newBalance := domain.Currency(req.Amount)
|
||||
err = s.walletStore.UpdateBalance(ctx, targetWallet.ID, newBalance)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update wallet balance: %w", err)
|
||||
}
|
||||
|
||||
return tx.Commit(ctx)
|
||||
}
|
||||
|
||||
func (s *Service) DepositUsingChapa(ctx context.Context, userID int64, req domain.ChapaDepositRequest) (string, error) {
|
||||
_, tx, err := s.store.BeginTx(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
user, err := s.userStore.GetUserByID(ctx, userID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
branch, err := s.branchStore.GetBranchByID(ctx, req.BranchID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
txID := uuid.New().String()
|
||||
|
||||
_, err = s.transactionStore.CreateTransaction(ctx, domain.CreateTransaction{
|
||||
Amount: req.Amount,
|
||||
Type: domain.TransactionType(domain.TRANSACTION_DEPOSIT),
|
||||
ReferenceNumber: txID,
|
||||
BranchID: req.BranchID,
|
||||
BranchName: branch.Name,
|
||||
BranchLocation: branch.Location,
|
||||
FullName: user.FirstName + " " + user.LastName,
|
||||
PhoneNumber: user.PhoneNumber,
|
||||
CompanyID: branch.CompanyID,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Fetch user details for Chapa payment
|
||||
userInfo, err := s.userStore.GetUserByID(ctx, userID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Build Chapa InitPaymentRequest (matches Chapa API)
|
||||
paymentReq := domain.InitPaymentRequest{
|
||||
Amount: req.Amount,
|
||||
Currency: req.Currency,
|
||||
Email: userInfo.Email,
|
||||
FirstName: userInfo.FirstName,
|
||||
LastName: userInfo.LastName,
|
||||
TxRef: txID,
|
||||
CallbackURL: s.config.CHAPA_CALLBACK_URL,
|
||||
ReturnURL: s.config.CHAPA_RETURN_URL,
|
||||
}
|
||||
|
||||
// Call Chapa to initialize payment
|
||||
paymentURL, err := s.chapaClient.InitPayment(ctx, paymentReq)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Commit DB transaction
|
||||
if err := tx.Commit(ctx); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return paymentURL, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import (
|
|||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/config"
|
||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/google/uuid"
|
||||
|
|
@ -299,7 +298,7 @@ func (h *Handler) VerifyChapaPayment(c *fiber.Ctx) error {
|
|||
}
|
||||
|
||||
switch txType.Type {
|
||||
case config.ChapaConfig.ChapaTransferType:
|
||||
case "Payout":
|
||||
var payload domain.ChapaWebHookTransfer
|
||||
if err := c.BodyParser(&payload); err != nil {
|
||||
return domain.UnProcessableEntityResponse(c)
|
||||
|
|
@ -315,7 +314,7 @@ func (h *Handler) VerifyChapaPayment(c *fiber.Ctx) error {
|
|||
StatusCode: fiber.StatusOK,
|
||||
})
|
||||
|
||||
case config.ChapaConfig.ChapaPaymentType:
|
||||
case "API":
|
||||
var payload domain.ChapaWebHookPayment
|
||||
if err := c.BodyParser(&payload); err != nil {
|
||||
return domain.UnProcessableEntityResponse(c)
|
||||
|
|
@ -339,3 +338,98 @@ func (h *Handler) VerifyChapaPayment(c *fiber.Ctx) error {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithdrawUsingChapa godoc
|
||||
// @Summary Withdraw using Chapa
|
||||
// @Description Initiates a withdrawal transaction using Chapa for the authenticated user.
|
||||
// @Tags Chapa
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body domain.ChapaWithdrawRequest true "Chapa Withdraw Request"
|
||||
// @Success 200 {object} domain.Response{data=string} "Withdrawal requested successfully"
|
||||
// @Failure 400 {object} domain.Response "Invalid request"
|
||||
// @Failure 401 {object} domain.Response "Unauthorized"
|
||||
// @Failure 422 {object} domain.Response "Unprocessable Entity"
|
||||
// @Failure 500 {object} domain.Response "Internal Server Error"
|
||||
// @Router /api/v1/chapa/payments/withdraw [post]
|
||||
func (h *Handler) WithdrawUsingChapa(c *fiber.Ctx) error {
|
||||
var req domain.ChapaWithdrawRequest
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return domain.UnProcessableEntityResponse(c)
|
||||
}
|
||||
|
||||
userID, ok := c.Locals("user_id").(int64)
|
||||
if !ok || userID == 0 {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(domain.Response{
|
||||
Message: "Unauthorized",
|
||||
Success: false,
|
||||
StatusCode: fiber.StatusUnauthorized,
|
||||
})
|
||||
}
|
||||
|
||||
if err := h.chapaSvc.WithdrawUsingChapa(c.Context(), userID, req); err != nil {
|
||||
return domain.FiberErrorResponse(c, err)
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(domain.Response{
|
||||
Message: "Withdrawal requested successfully",
|
||||
Success: true,
|
||||
StatusCode: fiber.StatusOK,
|
||||
})
|
||||
}
|
||||
|
||||
// DepositUsingChapa godoc
|
||||
// @Summary Deposit money into user wallet using Chapa
|
||||
// @Description Deposits money into user wallet from user account using Chapa
|
||||
// @Tags Chapa
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param payload body domain.ChapaDepositRequest true "Deposit request payload"
|
||||
// @Success 200 {object} domain.ChapaPaymentUrlResponseWrapper
|
||||
// @Failure 400 {object} domain.Response "Invalid request"
|
||||
// @Failure 422 {object} domain.Response "Validation error"
|
||||
// @Failure 500 {object} domain.Response "Internal server error"
|
||||
// @Router /api/v1/chapa/payments/deposit [post]
|
||||
func (h *Handler) DepositUsingChapa(c *fiber.Ctx) error {
|
||||
// Extract user info from token (adjust as per your auth middleware)
|
||||
userID, ok := c.Locals("user_id").(int64)
|
||||
if !ok || userID == 0 {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(domain.Response{
|
||||
Message: "Unauthorized",
|
||||
Success: false,
|
||||
StatusCode: fiber.StatusUnauthorized,
|
||||
})
|
||||
}
|
||||
|
||||
var req domain.ChapaDepositRequest
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return domain.UnProcessableEntityResponse(c)
|
||||
}
|
||||
|
||||
// Validate input in domain/model (you may have a Validate method)
|
||||
if err := req.Validate(); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(domain.Response{
|
||||
Message: err.Error(),
|
||||
Success: false,
|
||||
StatusCode: fiber.StatusBadRequest,
|
||||
})
|
||||
}
|
||||
|
||||
// Call service to handle the deposit logic and get payment URL
|
||||
paymentUrl, svcErr := h.chapaSvc.DepositUsingChapa(c.Context(), userID, req)
|
||||
if svcErr != nil {
|
||||
return domain.FiberErrorResponse(c, svcErr)
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(domain.ResponseWDataFactory[domain.ChapaPaymentUrlResponse]{
|
||||
Data: domain.ChapaPaymentUrlResponse{
|
||||
PaymentURL: paymentUrl,
|
||||
},
|
||||
Response: domain.Response{
|
||||
Message: "Deposit process started on wallet, fulfill payment using the URL provided",
|
||||
Success: true,
|
||||
StatusCode: fiber.StatusOK,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,13 +182,16 @@ func (a *App) initAppRoutes() {
|
|||
a.fiber.Post("/transfer/refill/:id", a.authMiddleware, h.RefillWallet)
|
||||
|
||||
//Chapa Routes
|
||||
group.Post("/chapa/payments/verify", h.VerifyChapaPayment)
|
||||
group.Post("/chapa/payments/withdraw", h.WithdrawUsingChapa)
|
||||
group.Post("/chapa/payments/deposit", h.DepositUsingChapa)
|
||||
|
||||
group.Post("/chapa/payments/initialize", h.InitializePayment)
|
||||
group.Get("/chapa/payments/verify/:tx_ref", h.VerifyTransaction)
|
||||
group.Post("/chapa/payments/callback", h.ReceiveWebhook)
|
||||
group.Get("/chapa/banks", h.GetBanks)
|
||||
group.Post("/chapa/transfers", h.CreateTransfer)
|
||||
group.Get("/chapa/transfers/verify/:transfer_ref", h.VerifyTransfer)
|
||||
// group.Post("/chapa/payments/initialize", h.InitializePayment)
|
||||
// group.Get("/chapa/payments/verify/:tx_ref", h.VerifyTransaction)
|
||||
// group.Post("/chapa/payments/callback", h.ReceiveWebhook)
|
||||
// group.Get("/chapa/banks", h.GetBanks)
|
||||
// group.Post("/chapa/transfers", h.CreateTransfer)
|
||||
// group.Get("/chapa/transfers/verify/:transfer_ref", h.VerifyTransfer)
|
||||
|
||||
//Alea Play Virtual Game Routes
|
||||
group.Get("/alea-play/launch", a.authMiddleware, h.LaunchAleaGame)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user