Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
Kachit committed Mar 21, 2022
1 parent 35bb739 commit 476b716
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 2 deletions.
24 changes: 22 additions & 2 deletions stubs/webhooks/send-callback/success.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
{
"code": 200,
"status": "success",
"message": "Request completed successfully.",
"data": {}
"message": "Callback Initiated Successfully",
"data": {
"payload": {
"id": 613589,
"request_amount": 520000,
"request_currency": "XAF",
"account_amount": 791.44,
"account_currency": "EUR",
"transaction_fee": 38.7806,
"total_credit": 752.6594,
"customer_charged": false,
"provider_id": "international_eur",
"merchant_reference": "123456789",
"internal_reference": "DUSUPAY5FNZCVUKZ8C0KZE",
"transaction_status": "COMPLETED",
"transaction_type": "collection",
"message": "Transaction Completed Successfully",
"account_number": "482100******1234",
"account_name": "GORDON ALF SHAMUEL",
"institution_name": "Visa - 3D"
}
}
}
51 changes: 51 additions & 0 deletions webhooks.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package dusupay

import (
"context"
"errors"
"fmt"
"net/http"
)

//WebhookInterface
type WebhookInterface interface {
GetPayloadString() string
Expand Down Expand Up @@ -62,7 +69,51 @@ type RefundWebhook struct {
Message string `json:"message"`
}

//WebhookResponse struct
type WebhookResponse struct {
*ResponseBody
Data *WebhookResponseData `json:"data,omitempty"`
}

//WebhookResponseData struct
type WebhookResponseData struct {
Payload *WebhookResponsePayload `json:"payload,omitempty"`
}

//WebhookResponsePayload struct
type WebhookResponsePayload struct {
ID int64 `json:"id"`
RequestAmount float64 `json:"request_amount"`
RequestCurrency string `json:"request_currency"`
AccountAmount float64 `json:"account_amount"`
AccountCurrency string `json:"account_currency"`
TransactionFee float64 `json:"transaction_fee"`
ProviderID string `json:"provider_id"`
MerchantReference string `json:"merchant_reference"`
InternalReference string `json:"internal_reference"`
TransactionStatus string `json:"transaction_status"`
TransactionType string `json:"transaction_type"`
Message string `json:"message"`
}

//WebhooksResource wrapper
type WebhooksResource struct {
*ResourceAbstract
}

//SendCallback (see https://docs.dusupay.com/appendix/webhooks/webhook-trigger)
func (r *WebhooksResource) SendCallback(ctx context.Context, internalReference string) (*WebhookResponse, *http.Response, error) {
rsp, err := r.ResourceAbstract.tr.Get(ctx, "v1/send-callback/"+internalReference, nil)
if err != nil {
return nil, nil, fmt.Errorf("WebhooksResource.SendCallback error: %v", err)
}
var response WebhookResponse
err = unmarshalResponse(rsp, &response)
if err != nil {
return nil, rsp, fmt.Errorf("WebhooksResource.SendCallback error: %v", err)
}
if !response.IsSuccess() {
err = errors.New(response.Message)
}
return &response, rsp, err
}
98 changes: 98 additions & 0 deletions webhooks_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package dusupay

import (
"context"
"encoding/json"
"github.com/jarcoal/httpmock"
"github.com/stretchr/testify/assert"
"io/ioutil"
"net/http"
"testing"
)

Expand Down Expand Up @@ -71,3 +75,97 @@ func Test_Webhooks_RefundWebhook_UnmarshalSuccess(t *testing.T) {
assert.Equal(t, "Refund Processed Successfully", webhook.Message)
assert.Equal(t, "4860610032773134", webhook.AccountNumber)
}

func Test_Webhooks_WebhooksResource_SendCallbackSuccess(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()

cfg := BuildStubConfig()
transport := BuildStubHttpTransport()

body, _ := LoadStubResponseData("stubs/webhooks/send-callback/success.json")
httpmock.RegisterResponder(http.MethodGet, cfg.Uri+"/v1/send-callback/qwerty", httpmock.NewBytesResponder(http.StatusOK, body))

ctx := context.Background()

resource := &WebhooksResource{ResourceAbstract: NewResourceAbstract(transport, cfg)}
result, resp, err := resource.SendCallback(ctx, "qwerty")
assert.NoError(t, err)
assert.NotEmpty(t, resp)
assert.NotEmpty(t, result)
//result
assert.True(t, result.IsSuccess())
assert.Equal(t, 200, result.Code)
assert.Equal(t, "success", result.Status)
assert.Equal(t, "Callback Initiated Successfully", result.Message)
assert.Equal(t, int64(613589), result.Data.Payload.ID)
assert.Equal(t, float64(520000), result.Data.Payload.RequestAmount)
assert.Equal(t, "XAF", result.Data.Payload.RequestCurrency)
assert.Equal(t, 791.44, result.Data.Payload.AccountAmount)
assert.Equal(t, "EUR", result.Data.Payload.AccountCurrency)
assert.Equal(t, 38.7806, result.Data.Payload.TransactionFee)
assert.Equal(t, "international_eur", result.Data.Payload.ProviderID)
assert.Equal(t, "123456789", result.Data.Payload.MerchantReference)
assert.Equal(t, "DUSUPAY5FNZCVUKZ8C0KZE", result.Data.Payload.InternalReference)
assert.Equal(t, "COMPLETED", result.Data.Payload.TransactionStatus)
assert.Equal(t, "collection", result.Data.Payload.TransactionType)
assert.Equal(t, "Transaction Completed Successfully", result.Data.Payload.Message)
//response
defer resp.Body.Close()
bodyRsp, _ := ioutil.ReadAll(resp.Body)
assert.Equal(t, body, bodyRsp)
}

func Test_Webhooks_WebhooksResource_SendCallbackJsonError(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()

cfg := BuildStubConfig()
transport := BuildStubHttpTransport()

body, _ := LoadStubResponseData("stubs/errors/401.json")
httpmock.RegisterResponder(http.MethodGet, cfg.Uri+"/v1/send-callback/qwerty", httpmock.NewBytesResponder(http.StatusOK, body))

ctx := context.Background()

resource := &WebhooksResource{ResourceAbstract: NewResourceAbstract(transport, cfg)}
result, resp, err := resource.SendCallback(ctx, "qwerty")
assert.Error(t, err)
assert.NotEmpty(t, resp)
assert.NotEmpty(t, result)
//result
assert.False(t, result.IsSuccess())
assert.Equal(t, 401, result.Code)
assert.Equal(t, "error", result.Status)
assert.Equal(t, "Unauthorized API access. Unknown Merchant", result.Message)
assert.Empty(t, result.Data)
//response
defer resp.Body.Close()
bodyRsp, _ := ioutil.ReadAll(resp.Body)
assert.Equal(t, body, bodyRsp)
//error
assert.Equal(t, "Unauthorized API access. Unknown Merchant", err.Error())
}

func Test_Webhooks_WebhooksResource_SendCallbackNonJsonError(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()

cfg := BuildStubConfig()
transport := BuildStubHttpTransport()

body, _ := LoadStubResponseData("stubs/errors/500.html")
httpmock.RegisterResponder(http.MethodGet, cfg.Uri+"/v1/send-callback/qwerty", httpmock.NewBytesResponder(http.StatusOK, body))

ctx := context.Background()

resource := &WebhooksResource{ResourceAbstract: NewResourceAbstract(transport, cfg)}
result, resp, err := resource.SendCallback(ctx, "qwerty")
assert.Error(t, err)
assert.NotEmpty(t, resp)
assert.Empty(t, result)
//response
defer resp.Body.Close()
bodyRsp, _ := ioutil.ReadAll(resp.Body)
assert.Equal(t, body, bodyRsp)
}

0 comments on commit 476b716

Please sign in to comment.