Skip to content

Commit

Permalink
Add endpoint for Shopify Payments transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
AlBaraa-mohamed committed Dec 31, 2023
1 parent e40406f commit 17b3409
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 0 deletions.
16 changes: 16 additions & 0 deletions fixtures/payments_transaction.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"id": 54534554564,
"type": "charge",
"test": false,
"payout_id": 1234,
"payout_status": "scheduled",
"currency": "USD",
"amount": "102.53",
"fee": "3.07",
"net": "102.53",
"source_id": 1234,
"source_type": "charge",
"source_order_transaction_id": 12,
"source_order_id": 1,
"processed_at": "2018-03-23T16:32:45Z"
}
52 changes: 52 additions & 0 deletions fixtures/payments_transactions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"transactions": [
{
"id": 699519475,
"type": "debit",
"test": false,
"payout_id": 623721858,
"payout_status": "paid",
"currency": "USD",
"amount": "-50.00",
"fee": "0.00",
"net": "-50.00",
"source_id": 460709370,
"source_type": "adjustment",
"source_order_id": null,
"source_order_transaction_id": null,
"processed_at": "2013-11-01"
},
{
"id": 77412310,
"type": "credit",
"test": false,
"payout_id": 623721858,
"payout_status": "paid",
"currency": "USD",
"amount": "50.00",
"fee": "0.00",
"net": "50.00",
"source_id": 374511569,
"source_type": "Payments::Balance::AdjustmentReversal",
"source_order_id": null,
"source_order_transaction_id": null,
"processed_at": "2013-11-01"
},
{
"id": 1006917261,
"type": "refund",
"test": false,
"payout_id": 623721858,
"payout_status": "paid",
"currency": "USD",
"amount": "-3.45",
"fee": "0.00",
"net": "-3.45",
"source_id": 1006917261,
"source_type": "Payments::Refund",
"source_order_id": 217130470,
"source_order_transaction_id": 1006917261,
"processed_at": "2013-11-01"
}
]
}
2 changes: 2 additions & 0 deletions goshopify.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ type Client struct {
AssignedFulfillmentOrder AssignedFulfillmentOrderService
FulfillmentEvent FulfillmentEventService
FulfillmentRequest FulfillmentRequestService
PaymentsTransactions PaymentsTransactionsService
}

// A general response error that follows a similar layout to Shopify's response
Expand Down Expand Up @@ -314,6 +315,7 @@ func NewClient(app App, shopName, token string, opts ...Option) *Client {
c.AssignedFulfillmentOrder = &AssignedFulfillmentOrderServiceOp{client: c}
c.FulfillmentEvent = &FulfillmentEventServiceOp{client: c}
c.FulfillmentRequest = &FulfillmentRequestServiceOp{client: c}
c.PaymentsTransactions = &PaymentsTransactionsServiceOp{client: c}

// apply any options
for _, opt := range opts {
Expand Down
108 changes: 108 additions & 0 deletions payments_transactions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package goshopify

import (
"fmt"
)

const paymentsTransactionsBasePath = "shopify_payments/balance/transactions"

// PaymentsTransactionsService is an interface for interfacing with the PaymentsTransactions endpoints of
// the Shopify API.
// See: https://shopify.dev/docs/api/admin-rest/2023-01/resources/transactions
type PaymentsTransactionsService interface {
List(interface{}) ([]PaymentsTransactions, error)
ListWithPagination(interface{}) ([]PaymentsTransactions, *Pagination, error)
Get(int64, interface{}) (*PaymentsTransactions, error)
}

// PaymentsTransactionsServiceOp handles communication with the payout related methods of the
// Shopify API.
type PaymentsTransactionsServiceOp struct {
client *Client
}

// A struct for all available payout list options
type PaymentsTransactionsListOptions struct {
PageInfo string `url:"page_info,omitempty"`
Limit int `url:"limit,omitempty"`
Fields string `url:"fields,omitempty"`
LastId int64 `url:"last_id,omitempty"`
SinceId int64 `url:"since_id,omitempty"`
PayoutId int64 `url:"payout_id,omitempty"`
PayoutStatus PayoutStatus `url:"payout_status,omitempty"`
DateMin *OnlyDate `url:"date_min,omitempty"`
DateMax *OnlyDate `url:"date_max,omitempty"`
Date *OnlyDate `url:"date,omitempty"`
}

// PaymentsTransactions represents a Shopify payout
type PaymentsTransactions struct {
ID int64 `json:"id"`
Type PaymentsTransactionsTypes `json:"type"`
Test bool `json:"test"`
PayoutID int `json:"payout_id"`
PayoutStatus PayoutStatus `json:"payout_status"`
Currency string `json:"currency"`
Amount string `json:"amount"`
Fee string `json:"fee"`
Net string `json:"net"`
SourceID int `json:"source_id"`
SourceType string `json:"source_type"`
SourceOrderTransactionID int `json:"source_order_transaction_id"`
SourceOrderID int `json:"source_order_id"`
ProcessedAt OnlyDate `json:"processed_at"`
}

type PaymentsTransactionsTypes string

const (
PaymentsTransactionsCharge PaymentsTransactionsTypes = "charge"
PaymentsTransactionsRefund PaymentsTransactionsTypes = "refund"
PaymentsTransactionsDispute PaymentsTransactionsTypes = "dispute"
PaymentsTransactionsReserve PaymentsTransactionsTypes = "reserve"
PaymentsTransactionsAdjustment PaymentsTransactionsTypes = "adjustment"
PaymentsTransactionsCredit PaymentsTransactionsTypes = "credit"
PaymentsTransactionsDebit PaymentsTransactionsTypes = "debit"
PaymentsTransactionsPayout PaymentsTransactionsTypes = "payout"
PaymentsTransactionsPayoutFailure PaymentsTransactionsTypes = "payout_failure"
PaymentsTransactionsPayoutCancellation PaymentsTransactionsTypes = "payout_cancellation"
)

// Represents the result from the PaymentsTransactions/X.json endpoint
type PaymentsTransactionResource struct {
PaymentsTransaction *PaymentsTransactions `json:"transaction"`
}

// Represents the result from the PaymentsTransactions.json endpoint
type PaymentsTransactionsResource struct {
PaymentsTransactions []PaymentsTransactions `json:"transactions"`
}

// List PaymentsTransactions
func (s *PaymentsTransactionsServiceOp) List(options interface{}) ([]PaymentsTransactions, error) {
PaymentsTransactions, _, err := s.ListWithPagination(options)
if err != nil {
return nil, err
}

Check warning on line 86 in payments_transactions.go

View check run for this annotation

Codecov / codecov/patch

payments_transactions.go#L85-L86

Added lines #L85 - L86 were not covered by tests
return PaymentsTransactions, nil
}

func (s *PaymentsTransactionsServiceOp) ListWithPagination(options interface{}) ([]PaymentsTransactions, *Pagination, error) {
path := fmt.Sprintf("%s.json", paymentsTransactionsBasePath)
resource := new(PaymentsTransactionsResource)

pagination, err := s.client.ListWithPagination(path, resource, options)
if err != nil {
return nil, nil, err
}

Check warning on line 97 in payments_transactions.go

View check run for this annotation

Codecov / codecov/patch

payments_transactions.go#L96-L97

Added lines #L96 - L97 were not covered by tests

return resource.PaymentsTransactions, pagination, nil
}

// Get individual payout
func (s *PaymentsTransactionsServiceOp) Get(payoutID int64, options interface{}) (*PaymentsTransactions, error) {
path := fmt.Sprintf("%s/%d.json", paymentsTransactionsBasePath, payoutID)
resource := new(PaymentsTransactionResource)
err := s.client.Get(path, resource, options)
return resource.PaymentsTransaction, err

Check warning on line 107 in payments_transactions.go

View check run for this annotation

Codecov / codecov/patch

payments_transactions.go#L103-L107

Added lines #L103 - L107 were not covered by tests
}
76 changes: 76 additions & 0 deletions payments_transactions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package goshopify

import (
"fmt"
"github.com/jarcoal/httpmock"
"reflect"
"testing"
"time"
)

func TestPaymentsTransactionsList(t *testing.T) {
setup()
defer teardown()

httpmock.RegisterResponder("GET", fmt.Sprintf("https://fooshop.myshopify.com/%s/shopify_payments/balance/transactions.json", client.pathPrefix),
httpmock.NewBytesResponder(200, loadFixture("payments_transactions.json")))
date1 := OnlyDate{time.Date(2013, 11, 01, 0, 0, 0, 0, time.UTC)}
paymentsTransactions, err := client.PaymentsTransactions.List(PaymentsTransactionsListOptions{PayoutId: 623721858})
if err != nil {
t.Errorf("PaymentsTransactions.List returned error: %v", err)
}

expected := []PaymentsTransactions{
{
ID: 699519475,
Type: PaymentsTransactionsDebit,
Test: false,
PayoutID: 623721858,
PayoutStatus: PayoutStatusPaid,
Currency: "USD",
Amount: "-50.00",
Fee: "0.00",
Net: "-50.00",
SourceID: 460709370,
SourceType: "adjustment",
SourceOrderID: 0,
SourceOrderTransactionID: 0,
ProcessedAt: date1,
},
{
ID: 77412310,
Type: PaymentsTransactionsCredit,
Test: false,
PayoutID: 623721858,
PayoutStatus: PayoutStatusPaid,
Currency: "USD",
Amount: "50.00",
Fee: "0.00",
Net: "50.00",
SourceID: 374511569,
SourceType: "Payments::Balance::AdjustmentReversal",
SourceOrderID: 0,
SourceOrderTransactionID: 0,
ProcessedAt: date1,
},
{
ID: 1006917261,
Type: PaymentsTransactionsRefund,
Test: false,
PayoutID: 623721858,
PayoutStatus: PayoutStatusPaid,
Currency: "USD",
Amount: "-3.45",
Fee: "0.00",
Net: "-3.45",
SourceID: 1006917261,
SourceType: "Payments::Refund",
SourceOrderID: 217130470,
SourceOrderTransactionID: 1006917261,
ProcessedAt: date1,
},
}
if !reflect.DeepEqual(paymentsTransactions, expected) {
t.Errorf("PaymentsTransactions.List returned %+v, expected %+v", paymentsTransactions, expected)
}
}

0 comments on commit 17b3409

Please sign in to comment.