diff --git a/integration_test.go b/integration_test.go index 900fa41..bc3a573 100644 --- a/integration_test.go +++ b/integration_test.go @@ -229,6 +229,67 @@ func TestGetPayments(t *testing.T) { } } +func TestPatchPayment(t *testing.T) { + c, _ := NewClient(testClientID, testSecret, APIBaseSandBox) + c.GetAccessToken() + + p := Payment{ + Intent: "sale", + Payer: &Payer{ + PaymentMethod: "paypal", + }, + Transactions: []Transaction{{ + Amount: &Amount{ + Currency: "USD", + Total: "10.00", // total cost including shipping + Details: Details{ + Shipping: "3.00", // total shipping cost + Subtotal: "7.00", // total cost without shipping + }, + }, + Description: "My Payment", + ItemList: &ItemList{ + Items: []Item{ + Item{ + Quantity: 2, + Price: "3.50", + Currency: "USD", + Name: "Product 1", + }, + }, + }, + Custom: "First value", + }}, + RedirectURLs: &RedirectURLs{ + ReturnURL: "http://..", + CancelURL: "http://..", + }, + } + NewPayment, err := c.CreatePayment(p) + if err != nil { + t.Errorf("Unexpected error %v", err) + } + PaymentID := NewPayment.ID + pp := []PaymentPatch{ + { + Operation: "replace", + Path: "/transactions/0/custom", + Value: "Replaced Value", + }, + } + RevisedPayment, errpp := c.PatchPayment(PaymentID, pp) + if errpp != nil { + t.Errorf("Unexpected error when patching %v", errpp) + } + if RevisedPayment.Transactions != nil && + len(RevisedPayment.Transactions) > 0 && + RevisedPayment.Transactions[0].Custom != "" { + if RevisedPayment.Transactions[0].Custom != "Replaced Value" { + t.Errorf("Patched payment value failed to be patched %v", RevisedPayment.Transactions[0].Custom) + } + } +} + func TestExecuteApprovedPayment(t *testing.T) { c, _ := NewClient(testClientID, testSecret, APIBaseSandBox) c.GetAccessToken() diff --git a/payment.go b/payment.go index a87a497..8bd95ec 100644 --- a/payment.go +++ b/payment.go @@ -111,6 +111,23 @@ func (c *Client) GetPayment(paymentID string) (*Payment, error) { return &p, nil } +// PatchPayment modifies some fields of a payment prior to execution +// Endpoint: PATCH /v1/payments/payment/ID +func (c *Client) PatchPayment(paymentID string, p []PaymentPatch) (*Payment, error) { + req, err := c.NewRequest("PATCH", fmt.Sprintf("%s/v1/payments/payment/%s", c.APIBase, paymentID), p) + if err != nil { + return nil, err + } + + response := Payment{} + + if err = c.SendWithAuth(req, &response); err != nil { + return nil, err + } + + return &response, nil +} + // GetPayments retrieve payments resources from Paypal // Endpoint: GET /v1/payments/payment/ func (c *Client) GetPayments() ([]Payment, error) { diff --git a/types.go b/types.go index 314e09d..a33e096 100644 --- a/types.go +++ b/types.go @@ -257,6 +257,7 @@ type ( ID string `json:"id"` Links []Link `json:"links"` State string `json:"state"` + Payer PaymentPayer `json:"payer"` Transactions []Transaction `json:"transactions,omitempty"` } @@ -331,6 +332,7 @@ type ( ShippingAddress *ShippingAddress `json:"shipping_address,omitempty"` TaxIDType string `json:"tax_id_type,omitempty"` TaxID string `json:"tax_id,omitempty"` + CountryCode string `json:"country_code"` } // Payment struct @@ -358,6 +360,20 @@ type ( ChargeModels []ChargeModel `json:"charge_models,omitempty"` } + // PaymentPatch PATCH /v1/payments/payment/{payment_id) + PaymentPatch struct { + Operation string `json:"op"` + Path string `json:"path"` + Value interface{} `json:"value"` + } + + // PaymentPayer struct + PaymentPayer struct { + PaymentMethod string `json:"payment_method"` + Status string `json:"status,omitempty"` + PayerInfo *PayerInfo `json:"payer_info,omitempty"` + } + // PaymentResponse structure PaymentResponse struct { ID string `json:"id"` diff --git a/unit_test.go b/unit_test.go index 327a7e6..bbfd71c 100644 --- a/unit_test.go +++ b/unit_test.go @@ -286,6 +286,46 @@ func TestTypePayoutItemResponse(t *testing.T) { } } +func TestTypePaymentPatch(t *testing.T) { + // test unmarshaling + response := `{ + "op": "replace", + "path": "/transactions/0/amount", + "value": "5" + }` + pp := &PaymentPatch{} + err := json.Unmarshal([]byte(response), pp) + if err != nil { + t.Errorf("TestTypePaymentPatch Unmarshal failed") + } + if pp.Operation != "replace" || + pp.Path != "/transactions/0/amount" || + pp.Value != "5" { + t.Errorf("PaymentPatch decoded result is incorrect, Given: %+v", pp) + } +} + +func TestTypePaymentPatchMarshal(t *testing.T) { + // test marshalling + p2 := &PaymentPatch{ + Operation: "add", + Path: "/transactions/0/amount", + Value: map[string]interface{}{ + "total": "18.37", + "currency": "EUR", + "details": map[string]interface{}{ + "subtotal": "13.37", + "shipping": "5.00", + }, + }, + } + p2expectedresponse := `{"op":"add","path":"/transactions/0/amount","value":{"currency":"EUR","details":{"shipping":"5.00","subtotal":"13.37"},"total":"18.37"}}` + response2, _ := json.Marshal(p2) + if string(response2) != string(p2expectedresponse) { + t.Errorf("PaymentPatch response2 is incorrect,\n Given: %+v\n Expected: %+v", string(response2), string(p2expectedresponse)) + } +} + // ServeHTTP implements http.Handler func (ts *webprofileTestServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { ts.t.Log(r.RequestURI)