mirror of
https://github.com/bestbytes/datatrans.git
synced 2025-10-16 12:05:36 +00:00
add context
This commit is contained in:
parent
415a8f7f76
commit
3e4652d535
65
client.go
65
client.go
@ -2,6 +2,7 @@ package datatrans
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
@ -191,7 +192,7 @@ func MarshalJSON(postData interface{}) ([]byte, error) {
|
||||
return jsonBytes, nil
|
||||
}
|
||||
|
||||
func (c *Client) prepareJSONReq(method, path string, postData interface{}) (*http.Request, error) {
|
||||
func (c *Client) prepareJSONReq(ctx context.Context, method, path string, postData interface{}) (*http.Request, error) {
|
||||
internalID := c.currentInternalID
|
||||
|
||||
var r io.Reader
|
||||
@ -209,7 +210,7 @@ func (c *Client) prepareJSONReq(method, path string, postData interface{}) (*htt
|
||||
host = endpointURLProduction
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, host+path, r)
|
||||
req, err := http.NewRequestWithContext(ctx, method, host+path, r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ClientID:%q: failed to create HTTP request: %w", internalID, err)
|
||||
}
|
||||
@ -230,7 +231,7 @@ func (c *Client) prepareJSONReq(method, path string, postData interface{}) (*htt
|
||||
|
||||
// Status allows once a transactionId has been received the status can be checked
|
||||
// with the Status API.
|
||||
func (c *Client) Status(transactionID string) (*ResponseStatus, error) {
|
||||
func (c *Client) Status(ctx context.Context, transactionID string) (*ResponseStatus, error) {
|
||||
if transactionID == "" {
|
||||
return nil, fmt.Errorf("transactionID cannot be empty")
|
||||
}
|
||||
@ -239,7 +240,7 @@ func (c *Client) Status(transactionID string) (*ResponseStatus, error) {
|
||||
if c.merchants[internalID].EnableProduction {
|
||||
host = endpointURLProduction
|
||||
}
|
||||
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf(host+pathStatus, transactionID), nil)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf(host+pathStatus, transactionID), nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ClientID:%q: failed to create HTTP request: %w", internalID, err)
|
||||
}
|
||||
@ -254,12 +255,12 @@ func (c *Client) Status(transactionID string) (*ResponseStatus, error) {
|
||||
|
||||
// Credit uses the credit API to credit a transaction which is in status settled.
|
||||
// The previously settled amount must not be exceeded.
|
||||
func (c *Client) Credit(transactionID string, rc RequestCredit) (*ResponseCardMasked, error) {
|
||||
func (c *Client) Credit(ctx context.Context, transactionID string, rc RequestCredit) (*ResponseCardMasked, error) {
|
||||
if transactionID == "" || rc.Currency == "" || rc.RefNo == "" {
|
||||
return nil, fmt.Errorf("neither currency nor refno nor transactionID can be empty")
|
||||
}
|
||||
|
||||
req, err := c.prepareJSONReq(http.MethodPost, fmt.Sprintf(pathCredit, transactionID), rc)
|
||||
req, err := c.prepareJSONReq(ctx, http.MethodPost, fmt.Sprintf(pathCredit, transactionID), rc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -275,12 +276,12 @@ func (c *Client) Credit(transactionID string, rc RequestCredit) (*ResponseCardMa
|
||||
// CreditAuthorize allows to use this API to make a credit without referring to a
|
||||
// previous authorization. This can be useful if you want to credit a cardholder
|
||||
// when there was no debit.
|
||||
func (c *Client) CreditAuthorize(rca RequestCreditAuthorize) (*ResponseCardMasked, error) {
|
||||
func (c *Client) CreditAuthorize(ctx context.Context, rca RequestCreditAuthorize) (*ResponseCardMasked, error) {
|
||||
if rca.Currency == "" || rca.RefNo == "" || rca.Amount == 0 {
|
||||
return nil, fmt.Errorf("neither currency nor refno nor amount can be empty")
|
||||
}
|
||||
|
||||
req, err := c.prepareJSONReq(http.MethodPost, pathCreditAuthorize, rca)
|
||||
req, err := c.prepareJSONReq(ctx, http.MethodPost, pathCreditAuthorize, rca)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -296,11 +297,11 @@ func (c *Client) CreditAuthorize(rca RequestCreditAuthorize) (*ResponseCardMaske
|
||||
// The transaction must either be in status authorized or settled. The
|
||||
// transactionId is needed to cancel an authorization.
|
||||
// https://api-reference.datatrans.ch/#operation/cancel
|
||||
func (c *Client) Cancel(transactionID string, refno string) error {
|
||||
func (c *Client) Cancel(ctx context.Context, transactionID string, refno string) error {
|
||||
if transactionID == "" || refno == "" {
|
||||
return fmt.Errorf("neither transactionID nor refno can be empty")
|
||||
}
|
||||
req, err := c.prepareJSONReq(http.MethodPost, fmt.Sprintf(pathCancel, transactionID), struct {
|
||||
req, err := c.prepareJSONReq(ctx, http.MethodPost, fmt.Sprintf(pathCancel, transactionID), struct {
|
||||
Refno string `json:"refno"`
|
||||
}{
|
||||
Refno: refno,
|
||||
@ -320,11 +321,11 @@ func (c *Client) Cancel(transactionID string, refno string) error {
|
||||
// transactionId is needed to settle an authorization. Note: This API call is not
|
||||
// needed if "autoSettle": true was used when initializing a transaction.
|
||||
// https://api-reference.datatrans.ch/#operation/settle
|
||||
func (c *Client) Settle(transactionID string, rs RequestSettle) error {
|
||||
func (c *Client) Settle(ctx context.Context, transactionID string, rs RequestSettle) error {
|
||||
if transactionID == "" || rs.Amount == 0 || rs.Currency == "" || rs.RefNo == "" {
|
||||
return fmt.Errorf("neither transactionID nor refno nor amount nor currency can be empty")
|
||||
}
|
||||
req, err := c.prepareJSONReq(http.MethodPost, fmt.Sprintf(pathSettle, transactionID), rs)
|
||||
req, err := c.prepareJSONReq(ctx, http.MethodPost, fmt.Sprintf(pathSettle, transactionID), rs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -340,11 +341,11 @@ func (c *Client) Settle(transactionID string, rs RequestSettle) error {
|
||||
// Only credit cards (including Apple Pay and Google Pay), PFC, KLN and PAP
|
||||
// support validation of an existing alias.
|
||||
// https://api-reference.datatrans.ch/#operation/validate
|
||||
func (c *Client) ValidateAlias(rva RequestValidateAlias) (*ResponseCardMasked, error) {
|
||||
func (c *Client) ValidateAlias(ctx context.Context, rva RequestValidateAlias) (*ResponseCardMasked, error) {
|
||||
if rva.Currency == "" || rva.RefNo == "" {
|
||||
return nil, fmt.Errorf("neither currency nor refno can be empty")
|
||||
}
|
||||
req, err := c.prepareJSONReq(http.MethodPost, pathValidate, rva)
|
||||
req, err := c.prepareJSONReq(ctx, http.MethodPost, pathValidate, rva)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -360,11 +361,11 @@ func (c *Client) ValidateAlias(rva RequestValidateAlias) (*ResponseCardMasked, e
|
||||
// transaction the parameter option.authenticationOnly was set to true, this API
|
||||
// can be used to authorize an already authenticated (3D) transaction.
|
||||
// https://api-reference.datatrans.ch/#operation/authorize-split
|
||||
func (c *Client) AuthorizeTransaction(transactionID string, rva RequestAuthorizeTransaction) (*ResponseAuthorize, error) {
|
||||
func (c *Client) AuthorizeTransaction(ctx context.Context, transactionID string, rva RequestAuthorizeTransaction) (*ResponseAuthorize, error) {
|
||||
if transactionID == "" || rva.RefNo == "" {
|
||||
return nil, fmt.Errorf("neither transactionID nor refno can be empty")
|
||||
}
|
||||
req, err := c.prepareJSONReq(http.MethodPost, fmt.Sprintf(pathAuthorizeTransaction, transactionID), rva)
|
||||
req, err := c.prepareJSONReq(ctx, http.MethodPost, fmt.Sprintf(pathAuthorizeTransaction, transactionID), rva)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -382,11 +383,11 @@ func (c *Client) AuthorizeTransaction(transactionID string, rva RequestAuthorize
|
||||
// the payment method specific objects (for example PAP) to see which parameters
|
||||
// so send. For credit cards, the card object can be used.
|
||||
// https://api-reference.datatrans.ch/#operation/authorize
|
||||
func (c *Client) Authorize(rva RequestAuthorize) (*ResponseCardMasked, error) {
|
||||
func (c *Client) Authorize(ctx context.Context, rva RequestAuthorize) (*ResponseCardMasked, error) {
|
||||
if rva.Amount == 0 || rva.Currency == "" || rva.RefNo == "" {
|
||||
return nil, fmt.Errorf("neither transactionID nor amount nor currency nor refno can be empty")
|
||||
}
|
||||
req, err := c.prepareJSONReq(http.MethodPost, pathAuthorize, rva)
|
||||
req, err := c.prepareJSONReq(ctx, http.MethodPost, pathAuthorize, rva)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -407,11 +408,11 @@ func (c *Client) Authorize(rva RequestAuthorize) (*ResponseCardMasked, error) {
|
||||
// Datatrans Payment Page with all the payment methods available for the given
|
||||
// merchantId. If you want to limit the number of payment methods, the
|
||||
// paymentMethod array can be used.
|
||||
func (c *Client) Initialize(rva RequestInitialize) (*ResponseInitialize, error) {
|
||||
func (c *Client) Initialize(ctx context.Context, rva RequestInitialize) (*ResponseInitialize, error) {
|
||||
if rva.Amount == 0 || rva.Currency == "" || rva.RefNo == "" {
|
||||
return nil, fmt.Errorf("neither amount nor currency nor refno can be empty")
|
||||
}
|
||||
req, err := c.prepareJSONReq(http.MethodPost, pathInitialize, rva)
|
||||
req, err := c.prepareJSONReq(ctx, http.MethodPost, pathInitialize, rva)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -426,11 +427,11 @@ func (c *Client) Initialize(rva RequestInitialize) (*ResponseInitialize, error)
|
||||
// InitializeSecureFields initializes a Secure Fields transaction. Proceed with
|
||||
// the steps below to process Secure Fields payment transactions.
|
||||
// https://api-reference.datatrans.ch/#operation/secureFieldsInit
|
||||
func (c *Client) SecureFieldsInit(rva RequestSecureFieldsInit) (*ResponseInitialize, error) {
|
||||
func (c *Client) SecureFieldsInit(ctx context.Context, rva RequestSecureFieldsInit) (*ResponseInitialize, error) {
|
||||
if rva.Amount == 0 || rva.Currency == "" || rva.ReturnUrl == "" {
|
||||
return nil, fmt.Errorf("neither amount nor currency nor returnURL can be empty")
|
||||
}
|
||||
req, err := c.prepareJSONReq(http.MethodPost, pathSecureFields, rva)
|
||||
req, err := c.prepareJSONReq(ctx, http.MethodPost, pathSecureFields, rva)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -446,11 +447,11 @@ func (c *Client) SecureFieldsInit(rva RequestSecureFieldsInit) (*ResponseInitial
|
||||
// transaction. This action is only allowed before the 3D process. At least one
|
||||
// property must be updated.
|
||||
// https://api-reference.datatrans.ch/#operation/secure-fields-update
|
||||
func (c *Client) SecureFieldsUpdate(transactionID string, rva RequestSecureFieldsUpdate) error {
|
||||
func (c *Client) SecureFieldsUpdate(ctx context.Context, transactionID string, rva RequestSecureFieldsUpdate) error {
|
||||
if rva.Amount == 0 || rva.Currency == "" {
|
||||
return fmt.Errorf("neither amount nor currency nor returnURL can be empty")
|
||||
}
|
||||
req, err := c.prepareJSONReq(http.MethodPatch, fmt.Sprintf(pathSecureFieldsUpdate, transactionID), rva)
|
||||
req, err := c.prepareJSONReq(ctx, http.MethodPatch, fmt.Sprintf(pathSecureFieldsUpdate, transactionID), rva)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -463,11 +464,11 @@ func (c *Client) SecureFieldsUpdate(transactionID string, rva RequestSecureField
|
||||
|
||||
// AliasConvert converts a legacy (numeric or masked) alias to the most recent
|
||||
// alias format.
|
||||
func (c *Client) AliasConvert(legacyAlias string) (string, error) {
|
||||
func (c *Client) AliasConvert(ctx context.Context, legacyAlias string) (string, error) {
|
||||
if legacyAlias == "" {
|
||||
return "", fmt.Errorf("legacyAlias cannot be empty")
|
||||
}
|
||||
req, err := c.prepareJSONReq(http.MethodPost, pathAliases, struct {
|
||||
req, err := c.prepareJSONReq(ctx, http.MethodPost, pathAliases, struct {
|
||||
LegacyAlias string `json:"legacyAlias"`
|
||||
}{
|
||||
LegacyAlias: legacyAlias,
|
||||
@ -486,11 +487,11 @@ func (c *Client) AliasConvert(legacyAlias string) (string, error) {
|
||||
|
||||
// AliasDelete deletes an alias with immediate effect. The alias will no longer
|
||||
// be recognized if used later with any API call.
|
||||
func (c *Client) AliasDelete(alias string) error {
|
||||
func (c *Client) AliasDelete(ctx context.Context, alias string) error {
|
||||
if alias == "" {
|
||||
return fmt.Errorf("alias cannot be empty")
|
||||
}
|
||||
req, err := c.prepareJSONReq(http.MethodDelete, fmt.Sprintf(pathAliasesDelete, alias), nil)
|
||||
req, err := c.prepareJSONReq(ctx, http.MethodDelete, fmt.Sprintf(pathAliasesDelete, alias), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -502,8 +503,8 @@ func (c *Client) AliasDelete(alias string) error {
|
||||
|
||||
// ReconciliationsSales reports a sale. When using reconciliation, use this API
|
||||
// to report a sale. The matching is based on the transactionId.
|
||||
func (c *Client) ReconciliationsSales(sale RequestReconciliationsSale) (*ResponseReconciliationsSale, error) {
|
||||
req, err := c.prepareJSONReq(http.MethodPost, pathReconciliationsSales, sale)
|
||||
func (c *Client) ReconciliationsSales(ctx context.Context, sale RequestReconciliationsSale) (*ResponseReconciliationsSale, error) {
|
||||
req, err := c.prepareJSONReq(ctx, http.MethodPost, pathReconciliationsSales, sale)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -517,8 +518,8 @@ func (c *Client) ReconciliationsSales(sale RequestReconciliationsSale) (*Respons
|
||||
// ReconciliationsSalesBulk reports bulk sales. When using reconciliation, use
|
||||
// this API to report multiples sales with a single API call. The matching is
|
||||
// based on the transactionId.
|
||||
func (c *Client) ReconciliationsSalesBulk(sales RequestReconciliationsSales) (*ResponseReconciliationsSales, error) {
|
||||
req, err := c.prepareJSONReq(http.MethodPost, pathReconciliationsSalesBulk, sales)
|
||||
func (c *Client) ReconciliationsSalesBulk(ctx context.Context, sales RequestReconciliationsSales) (*ResponseReconciliationsSales, error) {
|
||||
req, err := c.prepareJSONReq(ctx, http.MethodPost, pathReconciliationsSalesBulk, sales)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package datatrans_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@ -57,7 +58,7 @@ func TestClient_Status(t *testing.T) {
|
||||
)
|
||||
must(t, err)
|
||||
|
||||
rs, err := c.Status("3423423423")
|
||||
rs, err := c.Status(context.Background(), "3423423423")
|
||||
must(t, err)
|
||||
if rs.TransactionID != "210215103042148501" {
|
||||
t.Errorf("incorrect TransactionID:%q", rs.TransactionID)
|
||||
@ -100,7 +101,7 @@ func TestClient_Initialize(t *testing.T) {
|
||||
)
|
||||
must(t, err)
|
||||
|
||||
rs, err := c.Initialize(datatrans.RequestInitialize{
|
||||
rs, err := c.Initialize(context.Background(), datatrans.RequestInitialize{
|
||||
Currency: "CHF",
|
||||
RefNo: "872732",
|
||||
Amount: 1337,
|
||||
@ -170,7 +171,7 @@ func TestClient_AliasDelete_Error(t *testing.T) {
|
||||
)
|
||||
must(t, err)
|
||||
|
||||
err = c.AliasDelete("3469efdbbdcb043e56b19ffca69a8be0c5524d89")
|
||||
err = c.AliasDelete(context.Background(), "3469efdbbdcb043e56b19ffca69a8be0c5524d89")
|
||||
|
||||
var detailErr datatrans.ErrorResponse
|
||||
errors.As(err, &detailErr)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user