Skip to content

Commit

Permalink
Merge pull request #1 from Iknite-Space/exchange_rate_service_init_
Browse files Browse the repository at this point in the history
Implemented Transfers service
  • Loading branch information
AchoArnold authored Feb 1, 2025
2 parents 09cc28e + e79ea7e commit 2b959f8
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import "github.com/NdoleStudio/flutterwave-go"
- **Payments**
- `GET /v3/transactions/:id/verify`: Verify a transaction
- `POST /v3/transactions/:id/refund`: Create a Refund
- **Transfers**
- `GET /v3/transfers/rates`: Get the transfer rate of a transaction

## Usage

Expand Down
2 changes: 2 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type Client struct {
Bills *billsService
Payments *paymentsService
Transactions *transactionsService
Transfers *transfersService
}

// New creates and returns a new flutterwave.Client from a slice of flutterwave.ClientOption.
Expand All @@ -44,6 +45,7 @@ func New(options ...ClientOption) *Client {
client.Bills = (*billsService)(&client.common)
client.Payments = (*paymentsService)(&client.common)
client.Transactions = (*transactionsService)(&client.common)
client.Transfers = (*transfersService)(&client.common)
return client
}

Expand Down
21 changes: 21 additions & 0 deletions internal/stubs/api_responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,24 @@ func TransactionRefundResponse() []byte {
}
`)
}

// TransferRatesResponse is a dummy response for fetching the tranfer rate of a given transaction.
func TransferRateResponse() []byte {
return []byte(`
{
"status": "success",
"message": "Transfer amount fetched",
"data": {
"rate": 624.24,
"source": {
"currency": "NGN",
"amount": 624240
},
"destination": {
"currency": "USD",
"amount": 1000
}
}
}
`)
}
18 changes: 18 additions & 0 deletions transfers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package flutterwave

// ExchangeRateResponse is data returned when querying a transaction.
type TransferRateResponse struct {
Status string `json:"status"`
Message string `json:"message"`
Data struct {
Rate float64 `json:"rate"`
Source Payment `json:"source"`
Destination Payment `json:"destination"`
}
}

// Payment is data returned for either the source or the destination.
type Payment struct {
Currency string `json:"currency"`
Amount int `json:"amount"`
}
43 changes: 43 additions & 0 deletions transfers_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package flutterwave

import (
"context"
"encoding/json"
"net/http"
"strconv"
)

// transfersService is the API client for the `/v3/transfers` endpoint
type transfersService service

// Estimate the Transfer Rate of a transaction
//
// API Docs: https://developer.flutterwave.com/reference/check-transfer-rates
func (service *transfersService) Rate(ctx context.Context, amount int, destination_currency, source_currency string) (*TransferRateResponse, *Response, error) {
uri := "/v3/transfers/rates"

request, err := service.client.newRequest(ctx, http.MethodGet, uri, nil)
if err != nil {
return nil, nil, err
}

// Adding the parameters
requestWithParams := service.client.addURLParams(request, map[string]string{
"amount": strconv.Itoa(amount),
"destination_currency": destination_currency,
"source_currency": source_currency,
})

response, err := service.client.do(requestWithParams)
if err != nil {
return nil, response, err
}

var data TransferRateResponse
if err = json.Unmarshal(*response.Body, &data); err != nil {
return nil, response, err
}

return &data, response, nil

}
53 changes: 53 additions & 0 deletions transfers_service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package flutterwave

import (
"context"
"github.com/NdoleStudio/flutterwave-go/internal/helpers"
"github.com/NdoleStudio/flutterwave-go/internal/stubs"
"github.com/stretchr/testify/assert"
"net/http"
"testing"
)

func TestTransfersService_Rate(t *testing.T) {
// Setup
t.Parallel()

// Arrange
server := helpers.MakeTestServer(http.StatusOK, string(stubs.TransferRateResponse()))
client := New(WithBaseURL(server.URL))

// Act
rate, response, err := client.Transfers.Rate(context.Background(), 1000, "USD", "NGN")

// Assert
assert.Nil(t, err)

assert.Equal(t, http.StatusOK, response.HTTPResponse.StatusCode)
assert.Equal(t, stubs.TransferRateResponse(), *response.Body)
assert.Equal(t, 624240, rate.Data.Source.Amount)

// Teardown
server.Close()
}

func TestTransfersService_Rate_Failure(t *testing.T) {
// Setup
t.Parallel()

// Arrange
server := helpers.MakeTestServer(http.StatusInternalServerError, `{"error": "internal server error"}`)
client := New(WithBaseURL(server.URL))

// Act
rate, response, err := client.Transfers.Rate(context.Background(), 1000, "USD", "NGN")

// Assert
assert.NotNil(t, err) // Expect an error
assert.Nil(t, rate) // The rate should be nil due to failure
assert.Equal(t, http.StatusInternalServerError, response.HTTPResponse.StatusCode)
assert.Contains(t, err.Error(), "500") // Ensure error message contains 500

// Teardown
server.Close()
}

0 comments on commit 2b959f8

Please sign in to comment.