Skip to content

Commit ac7e7df

Browse files
committed
Add refund transaction API
1 parent 4001ccf commit ac7e7df

File tree

6 files changed

+128
-5
lines changed

6 files changed

+128
-5
lines changed

README.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,13 @@ import "github.com/NdoleStudio/flutterwave-go"
2727

2828
## Implemented
2929

30-
- [Status Codes](#bills)
31-
- `POST /bills/`: Create a bill payment
32-
- `GET /bill-items/{item_code}/validate`: Validate services like DSTV smartcard number, Meter number etc.
33-
- `GET /bills/{reference}`: Get the verbose status of a bill payment
30+
- **[Bills](#bills)**
31+
- `POST /bills/`: Create a bill payment
32+
- `GET /bill-items/{item_code}/validate`: Validate services like DStv smartcard number, Meter number etc.
33+
- `GET /bills/{reference}`: Get the verbose status of a bill payment
34+
- **Payments**
35+
- `GET /v3/transactions/:id/verify`: Verify a transaction
36+
- `POST /v3/transactions/:id/refund`: Create a Refund
3437

3538
## Usage
3639

@@ -46,7 +49,7 @@ import (
4649
)
4750

4851
func main() {
49-
flutterwaveClient := flutterwave.New(
52+
client := flutterwave.New(
5053
flutterwave.WithSecretKey("" /* flutterwave Secret Key */),
5154
)
5255
}
File renamed without changes.

internal/stubs/api_responses.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,27 @@ func BillsGetStatusVerboseResponse() string {
6464
}
6565
`
6666
}
67+
68+
// TransactionRefundResponse is a dummy response for refunding a transaction
69+
func TransactionRefundResponse() []byte {
70+
return []byte(`
71+
{
72+
"status": "success",
73+
"message": "Transaction refund initiated",
74+
"data": {
75+
"id": 75923,
76+
"account_id": 73362,
77+
"tx_id": 908790,
78+
"flw_ref": "URF_1577867664541_3572735",
79+
"wallet_id": 74639,
80+
"amount_refunded": 6900,
81+
"status": "completed",
82+
"destination": "payment_source",
83+
"meta": {
84+
"source": "availablebalance"
85+
},
86+
"created_at": "2021-01-24T09:18:37.366Z"
87+
}
88+
}
89+
`)
90+
}

transactions.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,23 @@ type TransactionResponse struct {
4444
} `json:"customer"`
4545
} `json:"data"`
4646
}
47+
48+
// RefundTransactionResponse is the payload generated when a transaction is refunded
49+
type RefundTransactionResponse struct {
50+
Status string `json:"status"`
51+
Message string `json:"message"`
52+
Data struct {
53+
ID int `json:"id"`
54+
AccountID int `json:"account_id"`
55+
TxID int `json:"tx_id"`
56+
FlwRef string `json:"flw_ref"`
57+
WalletID int `json:"wallet_id"`
58+
AmountRefunded int `json:"amount_refunded"`
59+
Status string `json:"status"`
60+
Destination string `json:"destination"`
61+
Meta struct {
62+
Source string `json:"source"`
63+
} `json:"meta"`
64+
CreatedAt time.Time `json:"created_at"`
65+
} `json:"data"`
66+
}

transactions_service.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,27 @@ func (service *transactionsService) Verify(ctx context.Context, transactionID in
3333

3434
return &data, response, nil
3535
}
36+
37+
// Refund a transaction
38+
//
39+
// API Docs: https://developer.flutterwave.com/reference/endpoints/transactions/#create-a-refund
40+
func (service *transactionsService) Refund(ctx context.Context, transactionID int64, amount int32) (*RefundTransactionResponse, *Response, error) {
41+
uri := fmt.Sprintf("/v3/transactions/%d/refund", transactionID)
42+
43+
request, err := service.client.newRequest(ctx, http.MethodPost, uri, map[string]int32{"amount": amount})
44+
if err != nil {
45+
return nil, nil, err
46+
}
47+
48+
response, err := service.client.do(request)
49+
if err != nil {
50+
return nil, response, err
51+
}
52+
53+
var data RefundTransactionResponse
54+
if err = json.Unmarshal(*response.Body, &data); err != nil {
55+
return nil, response, err
56+
}
57+
58+
return &data, response, nil
59+
}

transactions_service_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package flutterwave
2+
3+
import (
4+
"context"
5+
"github.com/NdoleStudio/flutterwave-go/internal/helpers"
6+
"github.com/NdoleStudio/flutterwave-go/internal/stubs"
7+
"github.com/stretchr/testify/assert"
8+
"net/http"
9+
"testing"
10+
)
11+
12+
func TestTransactionsService_Refund(t *testing.T) {
13+
// Setup
14+
t.Parallel()
15+
16+
// Arrange
17+
server := helpers.MakeTestServer(http.StatusOK, string(stubs.TransactionRefundResponse()))
18+
client := New(WithBaseURL(server.URL))
19+
20+
// Act
21+
refund, response, err := client.Transactions.Refund(context.Background(), 123, 200)
22+
23+
// Assert
24+
assert.Nil(t, err)
25+
26+
assert.Equal(t, http.StatusOK, response.HTTPResponse.StatusCode)
27+
assert.Equal(t, stubs.TransactionRefundResponse(), *response.Body)
28+
assert.Equal(t, 75923, refund.Data.ID)
29+
30+
// Teardown
31+
server.Close()
32+
}
33+
34+
func TestTransactionsService_RefundWithError(t *testing.T) {
35+
// Setup
36+
t.Parallel()
37+
38+
// Arrange
39+
server := helpers.MakeTestServer(http.StatusInternalServerError, "")
40+
client := New(WithBaseURL(server.URL))
41+
42+
// Act
43+
_, response, err := client.Transactions.Refund(context.Background(), 123, 200)
44+
45+
// Assert
46+
assert.NotNil(t, err)
47+
48+
assert.Equal(t, http.StatusInternalServerError, response.HTTPResponse.StatusCode)
49+
50+
// Teardown
51+
server.Close()
52+
}

0 commit comments

Comments
 (0)