Payments V2

This commit is contained in:
Alex Pliutau 2019-03-27 09:27:53 +01:00
parent 5af7837061
commit 4d9251997c
9 changed files with 50 additions and 499 deletions

116
README.md
View File

@ -6,24 +6,11 @@
### Go client for PayPal REST API
Currently supports **v1** only, v2 is in progress.
Currently supports **v2** only, if you want to use **v1**, use **v1.1.4** git tag.
### Coverage
* POST /v1/oauth2/token
* POST /v1/payments/payment
* GET /v1/payments/payment/**ID**
* GET /v1/payments/payment
* GET /v1/payments/authorization/**ID**
* POST /v1/payments/authorization/**ID**/capture
* POST /v1/payments/authorization/**ID**/void
* POST /v1/payments/authorization/**ID**/reauthorize
* GET /v1/payments/sale/**ID**
* POST /v1/payments/sale/**ID**/refund
* GET /v1/payments/refund/**ID**
* GET /v1/payments/orders/**ID**
* POST /v1/payments/orders/**ID**/authorize
* POST /v1/payments/orders/**ID**/capture
* POST /v1/payments/orders/**ID**/do-void
* POST /v1/identity/openidconnect/tokenservice
* GET /v1/identity/openidconnect/userinfo/?schema=**SCHEMA**
* POST /v1/payments/payouts
@ -40,10 +27,21 @@ Currently supports **v1** only, v2 is in progress.
* PATCH /v1/vault/credit-cards/**ID**
* GET /v1/vault/credit-cards/**ID**
* GET /v1/vault/credit-cards
* POST /v1/payments/billing-plans
* PATCH /v1/payments/billing-plans/***ID***
* POST /v1/payments/billing-agreements
* POST /v1/payments/billing-agreements/***TOKEN***/agreement-execute
* GET /v2/payments/authorization/**ID**
* POST /v2/payments/authorization/**ID**/capture
* POST /v2/payments/authorization/**ID**/void
* POST /v2/payments/authorization/**ID**/reauthorize
* GET /v2/payments/sale/**ID**
* POST /v2/payments/sale/**ID**/refund
* GET /v2/payments/refund/**ID**
* GET /v2/payments/orders/**ID**
* POST /v2/payments/orders/**ID**/authorize
* POST /v2/payments/orders/**ID**/capture
* POST /v2/payments/orders/**ID**/do-void
* POST /v2/payments/billing-plans
* PATCH /v2/payments/billing-plans/***ID***
* POST /v2/payments/billing-agreements
* POST /v2/payments/billing-agreements/***TOKEN***/agreement-execute
### Missing endpoints
It is possible that some endpoints are missing in this SDK Client, but you can use built-in **paypalsdk** functions to perform a request: **NewClient -> NewRequest -> SendWithAuth**
@ -60,86 +58,6 @@ c.SetLog(os.Stdout) // Set log to terminal stdout
accessToken, err := c.GetAccessToken()
```
### Create direct paypal payment
```go
amount := paypalsdk.Amount{
Total: "7.00",
Currency: "USD",
}
redirectURI := "http://example.com/redirect-uri"
cancelURI := "http://example.com/cancel-uri"
description := "Description for this payment"
paymentResult, err := c.CreateDirectPaypalPayment(amount, redirectURI, cancelURI, description)
```
### Create custom payment
```go
p := paypalsdk.Payment{
Intent: "sale",
Payer: &paypalsdk.Payer{
PaymentMethod: "credit_card",
FundingInstruments: []paypalsdk.FundingInstrument{paypalsdk.FundingInstrument{
CreditCard: &paypalsdk.CreditCard{
Number: "4111111111111111",
Type: "visa",
ExpireMonth: "11",
ExpireYear: "2020",
CVV2: "777",
FirstName: "John",
LastName: "Doe",
},
}},
},
Transactions: []paypalsdk.Transaction{paypalsdk.Transaction{
Amount: &paypalsdk.Amount{
Currency: "USD",
Total: "7.00",
},
Description: "My Payment",
}},
RedirectURLs: &paypalsdk.RedirectURLs{
ReturnURL: "http://...",
CancelURL: "http://...",
},
}
paymentResponse, err := client.CreatePayment(p)
```
### Execute approved payment
```go
paymentID := "PAY-17S8410768582940NKEE66EQ"
payerID := "7E7MGXCWTTKK2"
executeResult, err := c.ExecuteApprovedPayment(paymentID, payerID)
```
### Get payment by ID
```go
payment, err := c.GetPayment("PAY-17S8410768582940NKEE66EQ")
```
### Get list of payments
```go
payments, err := c.GetPayments()
//Or list payments with filters
filter := &paypalsdk.Filter{}
//With text fields
filter.AddTextField("sort_by").Is = "create_time"
filter.AddTextField("count").Is = "30"
filter.AddTextField("sort_order").Is = "desc"
//And time fields
filter.AddTimeField("start_time").Is = time.Now().Add(-time.Hour * 24 * 30)
filter.AddTimeField("end_time").Is = time.Now()
payments, err := c.GetPaymentsWithFilter(filter)
```
### Get authorization by ID
```go

View File

@ -8,10 +8,10 @@ import (
)
// GetAuthorization returns an authorization by ID
// Endpoint: GET /v1/payments/authorization/ID
// Endpoint: GET /v2/payments/authorization/ID
func (c *Client) GetAuthorization(authID string) (*Authorization, error) {
buf := bytes.NewBuffer([]byte(""))
req, err := http.NewRequest("GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v1/payments/authorization/", authID), buf)
req, err := http.NewRequest("GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v2/payments/authorization/", authID), buf)
if err != nil {
return &Authorization{}, err
}
@ -23,12 +23,12 @@ func (c *Client) GetAuthorization(authID string) (*Authorization, error) {
// CaptureAuthorization captures and process an existing authorization.
// To use this method, the original payment must have Intent set to "authorize"
// Endpoint: POST /v1/payments/authorization/ID/capture
// Endpoint: POST /v2/payments/authorization/ID/capture
func (c *Client) CaptureAuthorization(authID string, a *Amount, isFinalCapture bool) (*Capture, error) {
isFinalStr := strconv.FormatBool(isFinalCapture)
buf := bytes.NewBuffer([]byte(`{"amount":{"currency":"` + a.Currency + `,"total":"` + a.Total + `"},"is_final_capture":` + isFinalStr + `}`))
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/authorization/"+authID+"/capture"), buf)
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/authorization/"+authID+"/capture"), buf)
if err != nil {
return &Capture{}, err
}
@ -39,10 +39,10 @@ func (c *Client) CaptureAuthorization(authID string, a *Amount, isFinalCapture b
}
// VoidAuthorization voids a previously authorized payment
// Endpoint: POST /v1/payments/authorization/ID/void
// Endpoint: POST /v2/payments/authorization/ID/void
func (c *Client) VoidAuthorization(authID string) (*Authorization, error) {
buf := bytes.NewBuffer([]byte(""))
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/authorization/"+authID+"/void"), buf)
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/authorization/"+authID+"/void"), buf)
if err != nil {
return &Authorization{}, err
}
@ -54,10 +54,10 @@ func (c *Client) VoidAuthorization(authID string) (*Authorization, error) {
// ReauthorizeAuthorization reauthorize a Paypal account payment.
// PayPal recommends to reauthorize payment after ~3 days
// Endpoint: POST /v1/payments/authorization/ID/reauthorize
// Endpoint: POST /v2/payments/authorization/ID/reauthorize
func (c *Client) ReauthorizeAuthorization(authID string, a *Amount) (*Authorization, error) {
buf := bytes.NewBuffer([]byte(`{"amount":{"currency":"` + a.Currency + `","total":"` + a.Total + `"}}`))
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/authorization/"+authID+"/reauthorize"), buf)
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/authorization/"+authID+"/reauthorize"), buf)
if err != nil {
return &Authorization{}, err
}

View File

@ -48,9 +48,9 @@ type (
)
// CreateBillingPlan creates a billing plan in Paypal
// Endpoint: POST /v1/payments/billing-plans
// Endpoint: POST /v2/payments/billing-plans
func (c *Client) CreateBillingPlan(plan BillingPlan) (*CreateBillingResp, error) {
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-plans"), plan)
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/billing-plans"), plan)
response := &CreateBillingResp{}
if err != nil {
return response, err
@ -61,10 +61,10 @@ func (c *Client) CreateBillingPlan(plan BillingPlan) (*CreateBillingResp, error)
// ActivatePlan activates a billing plan
// By default, a new plan is not activated
// Endpoint: PATCH /v1/payments/billing-plans/
// Endpoint: PATCH /v2/payments/billing-plans/
func (c *Client) ActivatePlan(planID string) error {
buf := bytes.NewBuffer([]byte(`[{"op":"replace","path":"/","value":{"state":"ACTIVE"}}]`))
req, err := http.NewRequest("PATCH", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-plans/"+planID), buf)
req, err := http.NewRequest("PATCH", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/billing-plans/"+planID), buf)
if err != nil {
return err
}
@ -74,14 +74,14 @@ func (c *Client) ActivatePlan(planID string) error {
}
// CreateBillingAgreement creates an agreement for specified plan
// Endpoint: POST /v1/payments/billing-agreements
// Endpoint: POST /v2/payments/billing-agreements
func (c *Client) CreateBillingAgreement(a BillingAgreement) (*CreateAgreementResp, error) {
// PayPal needs only ID, so we will remove all fields except Plan ID
a.Plan = BillingPlan{
ID: a.Plan.ID,
}
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-agreements"), a)
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/billing-agreements"), a)
response := &CreateAgreementResp{}
if err != nil {
return response, err
@ -91,9 +91,9 @@ func (c *Client) CreateBillingAgreement(a BillingAgreement) (*CreateAgreementRes
}
// ExecuteApprovedAgreement - Use this call to execute (complete) a PayPal agreement that has been approved by the payer.
// Endpoint: POST /v1/payments/billing-agreements/token/agreement-execute
// Endpoint: POST /v2/payments/billing-agreements/token/agreement-execute
func (c *Client) ExecuteApprovedAgreement(token string) (*ExecuteAgreementResponse, error) {
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-agreements/"+token+"/agreement-execute"), nil)
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/billing-agreements/"+token+"/agreement-execute"), nil)
if err != nil {
return &ExecuteAgreementResponse{}, err
}
@ -115,9 +115,9 @@ func (c *Client) ExecuteApprovedAgreement(token string) (*ExecuteAgreementRespon
}
// ListBillingPlans lists billing-plans
// Endpoint: GET /v1/payments/billing-plans
// Endpoint: GET /v2/payments/billing-plans
func (c *Client) ListBillingPlans(bplp BillingPlanListParams) (*BillingPlanListResp, error) {
req, err := c.NewRequest("GET", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-plans"), nil)
req, err := c.NewRequest("GET", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/billing-plans"), nil)
q := req.URL.Query()
q.Add("page", bplp.Page)
q.Add("page_size", bplp.PageSize)

View File

@ -14,38 +14,4 @@ func Example() {
if err != nil {
panic(err)
}
// Create credit card payment
p := paypalsdk.Payment{
Intent: "sale",
Payer: &paypalsdk.Payer{
PaymentMethod: "credit_card",
FundingInstruments: []paypalsdk.FundingInstrument{{
CreditCard: &paypalsdk.CreditCard{
Number: "4111111111111111",
Type: "visa",
ExpireMonth: "11",
ExpireYear: "2020",
CVV2: "777",
FirstName: "John",
LastName: "Doe",
},
}},
},
Transactions: []paypalsdk.Transaction{{
Amount: &paypalsdk.Amount{
Currency: "USD",
Total: "7.00",
},
Description: "My Payment",
}},
RedirectURLs: &paypalsdk.RedirectURLs{
ReturnURL: "http://...",
CancelURL: "http://...",
},
}
_, err = c.CreatePayment(p)
if err != nil {
panic(err)
}
}

View File

@ -12,7 +12,6 @@ var testSecret = "EBzA1wRl5t73OMugOieDj_tI3vihfJmGl47ukQT-cpctooIzDu0K7IPESNC0cK
var testAuthID = "2DC87612EK520411B"
var testOrderID = "O-0PW72302W3743444R"
var testSaleID = "4CF18861HF410323U"
var testPaymentID = "PAY-5YK922393D847794YKER7MUI"
var testPayerID = "CR87QHB7JTRSC"
var testUserID = "https://www.paypal.com/webapps/auth/identity/user/WEssgRpQij92sE99_F9MImvQ8FPYgUEjrvCja2qH2H8"
var testCardID = "CARD-54E6956910402550WKGRL6EA"
@ -139,168 +138,6 @@ func TestVoidOrder(t *testing.T) {
}
}
func TestCreateDirectPaypalPayment(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
amount := Amount{
Total: "15.11",
Currency: "USD",
}
p, err := c.CreateDirectPaypalPayment(amount, "http://example.com", "http://example.com", "test payment")
if err != nil || p.ID == "" {
t.Errorf("Test paypal payment is not created, err: %v", err)
}
}
func TestCreatePayment(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
p := Payment{
Intent: "sale",
Payer: &Payer{
PaymentMethod: "credit_card",
FundingInstruments: []FundingInstrument{{
CreditCard: &CreditCard{
Number: "4111111111111111",
Type: "visa",
ExpireMonth: "11",
ExpireYear: "2020",
CVV2: "777",
FirstName: "John",
LastName: "Doe",
},
}},
},
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",
},
},
},
}},
RedirectURLs: &RedirectURLs{
ReturnURL: "http://..",
CancelURL: "http://..",
},
}
_, err := c.CreatePayment(p)
if err == nil {
t.Errorf("Expected error")
}
}
func TestGetPayment(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
_, err := c.GetPayment(testPaymentID)
if err == nil {
t.Errorf("404 for this payment ID")
}
}
func TestGetPayments(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
_, err := c.GetPayments()
if err != nil {
t.Errorf("Nil error expected, got: %s", err.Error())
}
}
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()
_, err := c.ExecuteApprovedPayment(testPaymentID, testPayerID)
if err == nil {
t.Errorf("404 for this payment ID")
}
}
func TestCreateSinglePayout(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()

View File

@ -3,11 +3,11 @@ package paypalsdk
import "fmt"
// GetOrder retrieves order by ID
// Endpoint: GET /v1/payments/orders/ID
// Endpoint: GET /v2/payments/orders/ID
func (c *Client) GetOrder(orderID string) (*Order, error) {
order := &Order{}
req, err := c.NewRequest("GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v1/payments/orders/", orderID), nil)
req, err := c.NewRequest("GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v2/payments/orders/", orderID), nil)
if err != nil {
return order, err
}
@ -20,7 +20,7 @@ func (c *Client) GetOrder(orderID string) (*Order, error) {
}
// AuthorizeOrder - Use this call to authorize an order.
// Endpoint: POST /v1/payments/orders/ID/authorize
// Endpoint: POST /v2/payments/orders/ID/authorize
func (c *Client) AuthorizeOrder(orderID string, amount *Amount) (*Authorization, error) {
type authRequest struct {
Amount *Amount `json:"amount"`
@ -28,7 +28,7 @@ func (c *Client) AuthorizeOrder(orderID string, amount *Amount) (*Authorization,
auth := &Authorization{}
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/orders/"+orderID+"/authorize"), authRequest{Amount: amount})
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/orders/"+orderID+"/authorize"), authRequest{Amount: amount})
if err != nil {
return auth, err
}
@ -41,7 +41,7 @@ func (c *Client) AuthorizeOrder(orderID string, amount *Amount) (*Authorization,
}
// CaptureOrder - Use this call to capture a payment on an order. To use this call, an original payment call must specify an intent of order.
// Endpoint: POST /v1/payments/orders/ID/capture
// Endpoint: POST /v2/payments/orders/ID/capture
func (c *Client) CaptureOrder(orderID string, amount *Amount, isFinalCapture bool, currency *Currency) (*Capture, error) {
type captureRequest struct {
Amount *Amount `json:"amount"`
@ -51,7 +51,7 @@ func (c *Client) CaptureOrder(orderID string, amount *Amount, isFinalCapture boo
capture := &Capture{}
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/orders/"+orderID+"/capture"), captureRequest{Amount: amount, IsFinalCapture: isFinalCapture, Currency: currency})
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/orders/"+orderID+"/capture"), captureRequest{Amount: amount, IsFinalCapture: isFinalCapture, Currency: currency})
if err != nil {
return capture, err
}
@ -65,11 +65,11 @@ func (c *Client) CaptureOrder(orderID string, amount *Amount, isFinalCapture boo
// VoidOrder - Use this call to void an existing order.
// Note: An order cannot be voided if payment has already been partially or fully captured.
// Endpoint: POST /v1/payments/orders/ID/do-void
// Endpoint: POST /v2/payments/orders/ID/do-void
func (c *Client) VoidOrder(orderID string) (*Order, error) {
order := &Order{}
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/orders/"+orderID+"/do-void"), nil)
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/orders/"+orderID+"/do-void"), nil)
if err != nil {
return order, err
}

View File

@ -1,156 +0,0 @@
package paypalsdk
import (
"bytes"
"errors"
"fmt"
"net/http"
)
// ListPaymentsResp slice of payments
type ListPaymentsResp struct {
Payments []Payment `json:"payments"`
}
// CreatePaymentResp contains Payment Info and Links slice
type CreatePaymentResp struct {
*Payment
Links []Link `json:"links"`
}
// CreateDirectPaypalPayment sends request to create a payment with payment_method=paypal
// CreatePayment is more common function for any kind of payment
// Endpoint: POST /v1/payments/payment
func (c *Client) CreateDirectPaypalPayment(amount Amount, redirectURI string, cancelURI string, description string) (*PaymentResponse, error) {
buf := bytes.NewBuffer([]byte(`{"intent":"sale","payer":{"payment_method":"paypal"},` +
`"transactions":[{"amount":{"total":"` + amount.Total +
`","currency":"` + amount.Currency + `"},"description":"` + description + `"}],"redirect_urls":{"return_url":"` +
redirectURI + `","cancel_url":"` + cancelURI + `"}}`))
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/payment"), buf)
if err != nil {
return &PaymentResponse{}, err
}
req.SetBasicAuth(c.ClientID, c.Secret)
req.Header.Set("Authorization", "Bearer "+c.Token.Token)
p := PaymentResponse{}
if err = c.SendWithAuth(req, &p); err != nil {
return &p, err
}
if p.ID == "" {
return &p, errors.New("Unable to create payment with this access token")
}
return &p, err
}
// CreatePayment creates a payment in Paypal
// Depending on the payment_method and the funding_instrument, you can use the payment resource for direct credit card payments, stored credit card payments, or PayPal account payments.
// Endpoint: POST /v1/payments/payment
func (c *Client) CreatePayment(p Payment) (*CreatePaymentResp, error) {
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/payment"), p)
if err != nil {
return &CreatePaymentResp{}, err
}
response := &CreatePaymentResp{}
if err = c.SendWithAuth(req, response); err != nil {
return response, err
}
return response, nil
}
// ExecuteApprovedPayment - Use this call to execute (complete) a PayPal payment that has been approved by the payer. You can optionally update transaction information when executing the payment by passing in one or more transactions.
// Endpoint: POST /v1/payments/payment/paymentID/execute
func (c *Client) ExecuteApprovedPayment(paymentID string, payerID string) (*ExecuteResponse, error) {
buf := bytes.NewBuffer([]byte(`{"payer_id":"` + payerID + `"}`))
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/payment/"+paymentID+"/execute"), buf)
if err != nil {
return &ExecuteResponse{}, err
}
req.SetBasicAuth(c.ClientID, c.Secret)
req.Header.Set("Authorization", "Bearer "+c.Token.Token)
e := ExecuteResponse{}
if err = c.SendWithAuth(req, &e); err != nil {
return &e, err
}
if e.ID == "" {
return &e, errors.New("Unable to execute payment with paymentID=" + paymentID)
}
return &e, err
}
// GetPayment gets a payment from PayPal
// Endpoint: GET /v1/payments/payment/ID
func (c *Client) GetPayment(paymentID string) (*Payment, error) {
p := Payment{}
req, err := http.NewRequest("GET", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/payment/"+paymentID), nil)
if err != nil {
return &p, err
}
if err = c.SendWithAuth(req, &p); err != nil {
return &p, err
}
if p.ID == "" {
return &p, errors.New("Unable to get payment with paymentID=" + paymentID)
}
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) {
return c.getPayments(nil)
}
// GetPaymentsWithFilter retrieve payments resources from Paypal by the provided filter
// Endpoint: GET /v1/payments/payment/
func (c *Client) GetPaymentsWithFilter(filter *Filter) ([]Payment, error) {
return c.getPayments(filter)
}
func (c *Client) getPayments(filter *Filter) ([]Payment, error) {
var p ListPaymentsResp
req, err := http.NewRequest("GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v1/payments/payment/", filter), nil)
if err != nil {
return p.Payments, err
}
if err = c.SendWithAuth(req, &p); err != nil {
return p.Payments, err
}
return p.Payments, nil
}

12
sale.go
View File

@ -5,11 +5,11 @@ import "fmt"
// GetSale returns a sale by ID
// Use this call to get details about a sale transaction.
// Note: This call returns only the sales that were created via the REST API.
// Endpoint: GET /v1/payments/sale/ID
// Endpoint: GET /v2/payments/sale/ID
func (c *Client) GetSale(saleID string) (*Sale, error) {
sale := &Sale{}
req, err := c.NewRequest("GET", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/sale/"+saleID), nil)
req, err := c.NewRequest("GET", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/sale/"+saleID), nil)
if err != nil {
return sale, err
}
@ -23,7 +23,7 @@ func (c *Client) GetSale(saleID string) (*Sale, error) {
// RefundSale refunds a completed payment.
// Use this call to refund a completed payment. Provide the sale_id in the URI and an empty JSON payload for a full refund. For partial refunds, you can include an amount.
// Endpoint: POST /v1/payments/sale/ID/refund
// Endpoint: POST /v2/payments/sale/ID/refund
func (c *Client) RefundSale(saleID string, a *Amount) (*Refund, error) {
type refundRequest struct {
Amount *Amount `json:"amount"`
@ -31,7 +31,7 @@ func (c *Client) RefundSale(saleID string, a *Amount) (*Refund, error) {
refund := &Refund{}
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/sale/"+saleID+"/refund"), &refundRequest{Amount: a})
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/sale/"+saleID+"/refund"), &refundRequest{Amount: a})
if err != nil {
return refund, err
}
@ -45,11 +45,11 @@ func (c *Client) RefundSale(saleID string, a *Amount) (*Refund, error) {
// GetRefund by ID
// Use it to look up details of a specific refund on direct and captured payments.
// Endpoint: GET /v1/payments/refund/ID
// Endpoint: GET /v2/payments/refund/ID
func (c *Client) GetRefund(refundID string) (*Refund, error) {
refund := &Refund{}
req, err := c.NewRequest("GET", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/refund/"+refundID), nil)
req, err := c.NewRequest("GET", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/refund/"+refundID), nil)
if err != nil {
return refund, err
}

View File

@ -356,20 +356,6 @@ type (
CountryCode string `json:"country_code"`
}
// Payment struct
Payment struct {
Intent string `json:"intent"`
Payer *Payer `json:"payer"`
ApplicationContext *ApplicationContext `json:"application_context,omitempty"`
Transactions []Transaction `json:"transactions"`
RedirectURLs *RedirectURLs `json:"redirect_urls,omitempty"`
ID string `json:"id,omitempty"`
CreateTime *time.Time `json:"create_time,omitempty"`
State string `json:"state,omitempty"`
UpdateTime *time.Time `json:"update_time,omitempty"`
ExperienceProfileID string `json:"experience_profile_id,omitempty"`
}
// PaymentDefinition struct
PaymentDefinition struct {
ID string `json:"id,omitempty"`
@ -387,7 +373,7 @@ type (
AllowedPaymentMethod string `json:"allowed_payment_method,omitempty"`
}
// PaymentPatch PATCH /v1/payments/payment/{payment_id)
// PaymentPatch PATCH /v2/payments/payment/{payment_id)
PaymentPatch struct {
Operation string `json:"op"`
Path string `json:"path"`