Skip to content

Commit

Permalink
Add direct masterpass integration
Browse files Browse the repository at this point in the history
  • Loading branch information
onurpolattimur committed Sep 13, 2023
1 parent 3f4d61b commit 4066e17
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 27 deletions.
2 changes: 2 additions & 0 deletions adapter/craftgate.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ type Client struct {
FileReporting *FileReporting
Fraud *Fraud
Hook *Hook
Masterpass *Masterpass
}

func New(apiKey, apiSecret, baseURL string, opts ...ClientOption) (*Client, error) {
Expand Down Expand Up @@ -117,6 +118,7 @@ func newClient(apiKey, secretKey string) *Client {
client.FileReporting = &FileReporting{Client: client}
client.Fraud = &Fraud{Client: client}
client.Hook = &Hook{Client: client}
client.Masterpass = &Masterpass{Client: client}

return client
}
Expand Down
85 changes: 85 additions & 0 deletions adapter/masterpass.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package adapter

import (
"context"
"net/http"
)

type Masterpass struct {
Client *Client
}

func (api *Masterpass) CheckMasterpassUser(ctx context.Context, request CheckMasterpassUserRequest) (*CheckMasterpassUserResponse, error) {
newRequest, err := api.Client.NewRequest(ctx, http.MethodPost, "payment/v1/masterpass-payments/check-user", request)
if err != nil {
return nil, err
}

response := &Response[CheckMasterpassUserResponse]{}
err = api.Client.Do(ctx, newRequest, response)
if err != nil {
return nil, err
}

return response.Data, nil
}

func (api *Masterpass) GenerateMasterpassPaymentToken(ctx context.Context, request MasterpassPaymentTokenGenerateRequest) (*MasterpassPaymentTokenGenerateResponse, error) {
newRequest, err := api.Client.NewRequest(ctx, http.MethodPost, "payment/v2/masterpass-payments/generate-token", request)
if err != nil {
return nil, err
}

response := &Response[MasterpassPaymentTokenGenerateResponse]{}
err = api.Client.Do(ctx, newRequest, response)
if err != nil {
return nil, err
}

return response.Data, nil
}

func (api *Masterpass) CompleteMasterpassPayment(ctx context.Context, request MasterpassPaymentCompleteRequest) (*PaymentResponse, error) {
newRequest, err := api.Client.NewRequest(ctx, http.MethodPost, "payment/v2/masterpass-payments/complete", request)
if err != nil {
return nil, err
}

response := &Response[PaymentResponse]{}
err = api.Client.Do(ctx, newRequest, response)
if err != nil {
return nil, err
}

return response.Data, nil
}

func (api *Masterpass) Init3DSMasterpassPayment(ctx context.Context, request MasterpassPaymentThreeDSInitRequest) (*MasterpassPaymentThreeDSInitResponse, error) {
newRequest, err := api.Client.NewRequest(ctx, http.MethodPost, "payment/v2/masterpass-payments/3ds-init", request)
if err != nil {
return nil, err
}

response := &Response[MasterpassPaymentThreeDSInitResponse]{}
err = api.Client.Do(ctx, newRequest, response)
if err != nil {
return nil, err
}

return response.Data, nil
}

func (api *Masterpass) Complete3DSMasterpassPayment(ctx context.Context, request MasterpassPaymentThreeDSCompleteRequest) (*PaymentResponse, error) {
newRequest, err := api.Client.NewRequest(ctx, http.MethodPost, "payment/v2/masterpass-payments/3ds-complete", request)
if err != nil {
return nil, err
}

response := &Response[PaymentResponse]{}
err = api.Client.Do(ctx, newRequest, response)
if err != nil {
return nil, err
}

return response.Data, nil
}
50 changes: 50 additions & 0 deletions adapter/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,28 @@ type SearchPayoutAccountRequest struct {
Size int `schema:"size,omitempty"`
}

type MasterpassPaymentTokenGenerateRequest struct {
Msisdn string `json:"msisdn,omitempty"`
UserId string `json:"userId,omitempty"`
BinNumber string `json:"binNumber,omitempty"`
ForceThreeDS bool `json:"forceThreeDS,omitempty"`
CreatePayment MasterpassCreatePayment `json:"createPayment,omitempty"`
}

type MasterpassPaymentCompleteRequest struct {
ReferenceId string `json:"referenceId,omitempty"`
Token string `json:"token,omitempty"`
}

type MasterpassPaymentThreeDSInitRequest struct {
ReferenceId string `json:"referenceId,omitempty"`
CallbackUrl string `json:"callbackUrl,omitempty"`
}

type MasterpassPaymentThreeDSCompleteRequest struct {
PaymentId int64 `json:"paymentId,omitempty"`
}

// responses
type PaymentResponse struct {
Id *int64 `json:"id"`
Expand Down Expand Up @@ -742,6 +764,16 @@ type PayoutAccountResponse struct {
SubMerchantMemberId *int64 `json:"subMerchantMemberId"`
}

type MasterpassPaymentThreeDSInitResponse struct {
ReturnUrl *string `json:"returnUrl"`
}

type MasterpassPaymentTokenGenerateResponse struct {
Token *string `json:"token"`
ReferenceId *string `json:"referenceId"`
OrderNo *string `json:"orderNo"`
}

type RefundWalletTransactionRequest struct {
RefundPrice float64 `json:"refundPrice"`
}
Expand Down Expand Up @@ -1544,6 +1576,24 @@ type PaymentItem struct {
SubMerchantMemberPrice float64 `json:"subMerchantMemberPrice,omitempty"`
}

type MasterpassCreatePayment struct {
Price float64 `json:"price,omitempty"`
PaidPrice float64 `json:"paidPrice,omitempty"`
PosAlias string `json:"posAlias,omitempty"`
Installment int `json:"installment,omitempty"`
Currency Currency `json:"currency,omitempty"`
PaymentGroup PaymentGroup `json:"paymentGroup,omitempty"`
ConversationId string `json:"conversationId,omitempty"`
ExternalId string `json:"externalId,omitempty"`
ClientIp string `json:"clientIp,omitempty"`
PaymentPhase PaymentPhase `json:"paymentPhase,omitempty"`
PaymentChannel string `json:"paymentChannel,omitempty"`
BuyerMemberId int64 `json:"buyerMemberId,omitempty"`
BankOrderId string `json:"bankOrderId,omitempty"`
Items []PaymentItem `json:"items"`
AdditionalParams map[string]interface{} `json:"additionalParams,omitempty"`
}

type PaymentError ErrorResponse

type Void struct {
Expand Down
15 changes: 0 additions & 15 deletions adapter/payment.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,21 +474,6 @@ func (api *Payment) DisapprovePaymentTransactions(ctx context.Context, request P
return response.Data, nil
}

func (api *Payment) CheckMasterpassUser(ctx context.Context, request CheckMasterpassUserRequest) (*CheckMasterpassUserResponse, error) {
newRequest, err := api.Client.NewRequest(ctx, http.MethodPost, "payment/v1/masterpass-payments/check-user", request)
if err != nil {
return nil, err
}

response := &Response[CheckMasterpassUserResponse]{}
err = api.Client.Do(ctx, newRequest, response)
if err != nil {
return nil, err
}

return response.Data, nil
}

func (c *Payment) Is3DSecureCallbackVerified(threeDSecureCallbackKey string, params map[string]string) bool {
hash := params["hash"]
hashString := strings.Join([]string{threeDSecureCallbackKey,
Expand Down
103 changes: 103 additions & 0 deletions tests/masterpass_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package tests

import (
"context"
"github.com/craftgate/craftgate-go-client/adapter"
craftgate "github.com/craftgate/craftgate-go-client/adapter"
"github.com/davecgh/go-spew/spew"
"github.com/stretchr/testify/require"
"testing"
)

var masterpassClient, _ = craftgate.New("api-key", "secret-key", "https://sandbox-api.craftgate.io")

func TestMasterpass_CheckMasterpassUser(t *testing.T) {
request := adapter.CheckMasterpassUserRequest{
MasterpassGsmNumber: "903000000000",
}
res, err := masterpassClient.Masterpass.CheckMasterpassUser(context.Background(), request)
_, _ = spew.Printf("%#v\n", res)

if err != nil {
t.Errorf("Error %s", err)
}
}

func TestMasterpass_GenerateMasterpassPaymentToken(t *testing.T) {
request := adapter.MasterpassPaymentTokenGenerateRequest{
UserId: "masterpass-user-id",
Msisdn: "900000000000",
BinNumber: "404308",
ForceThreeDS: true,
CreatePayment: craftgate.MasterpassCreatePayment{
Price: 1.25,
PaidPrice: 1.25,
Installment: 1,
Currency: craftgate.TRY,
PaymentGroup: craftgate.LISTING_OR_SUBSCRIPTION,
ConversationId: "foo-bar",
ExternalId: "115",
Items: []craftgate.PaymentItem{
{
Name: "Item 1",
Price: 1,
ExternalId: "1",
},
{
Name: "Item 2",
Price: 0.25,
ExternalId: "2",
},
},
},
}

res, err := masterpassClient.Masterpass.GenerateMasterpassPaymentToken(context.Background(), request)

require.NotNil(t, res.Token)
require.NotNil(t, res.ReferenceId)
if err != nil {
t.Errorf("Error %s", err)
}
}

func TestMasterpass_CompleteMasterpassPayment(t *testing.T) {
request := adapter.MasterpassPaymentCompleteRequest{
ReferenceId: "referenceId",
Token: "token",
}

res, err := masterpassClient.Masterpass.CompleteMasterpassPayment(context.Background(), request)

require.NotNil(t, res.Id)
if err != nil {
t.Errorf("Error %s", err)
}
}

func TestMasterpass_Init3DSMasterpassPayment(t *testing.T) {
request := adapter.MasterpassPaymentThreeDSInitRequest{
ReferenceId: "referenceId",
CallbackUrl: "https://www.your-website.com/craftgate-3DSecure-callback",
}

res, err := masterpassClient.Masterpass.Init3DSMasterpassPayment(context.Background(), request)

require.NotNil(t, res.ReturnUrl)
if err != nil {
t.Errorf("Error %s", err)
}
}

func TestMasterpass_Complete3DSMasterpassPayment(t *testing.T) {
request := adapter.MasterpassPaymentThreeDSCompleteRequest{
PaymentId: 1,
}

res, err := masterpassClient.Masterpass.Complete3DSMasterpassPayment(context.Background(), request)

require.NotNil(t, res.Id)
if err != nil {
t.Errorf("Error %s", err)
}
}
12 changes: 0 additions & 12 deletions tests/payment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -633,18 +633,6 @@ func TestPayment_DisapprovePaymentTransactions(t *testing.T) {
}
}

func TestPayment_CheckMasterpassUser(t *testing.T) {
request := adapter.CheckMasterpassUserRequest{
MasterpassGsmNumber: "903000000000",
}
res, err := paymentClient.Payment.CheckMasterpassUser(context.Background(), request)
_, _ = spew.Printf("%#v\n", res)

if err != nil {
t.Errorf("Error %s", err)
}
}

func TestPayment_Verify3DSCallback(t *testing.T) {
merchantThreeDsCallbackKey := "merchantThreeDsCallbackKeySndbox"

Expand Down

0 comments on commit 4066e17

Please sign in to comment.