add context support

This commit is contained in:
Thomas Frössman 2021-01-03 10:28:52 +01:00
parent 0f9d1cca16
commit cc8b3cee69
21 changed files with 235 additions and 210 deletions

View File

@ -1,7 +1,8 @@
language: go
go:
- 1.11
- 1.12
- 1.13
- 1.14
- 1.15
install:
- export PATH=$PATH:$HOME/gopath/bin
script:

View File

@ -82,14 +82,14 @@ It is possible that some endpoints are missing in this SDK Client, but you can u
```go
// If using Go Modules
// import "github.com/plutov/paypal/v3"
// import "github.com/plutov/paypal/v4"
import "github.com/plutov/paypal"
// Create a client instance
c, err := paypal.NewClient("clientID", "secretID", paypal.APIBaseSandBox)
c.SetLog(os.Stdout) // Set log to terminal stdout
accessToken, err := c.GetAccessToken()
accessToken, err := c.GetAccessToken(context.Background())
```
### How to Contribute

View File

@ -2,15 +2,16 @@ package paypal
import (
"bytes"
"context"
"fmt"
"net/http"
)
// GetAuthorization returns an authorization by ID
// Endpoint: GET /v2/payments/authorizations/ID
func (c *Client) GetAuthorization(authID string) (*Authorization, error) {
func (c *Client) GetAuthorization(ctx context.Context, authID string) (*Authorization, error) {
buf := bytes.NewBuffer([]byte(""))
req, err := http.NewRequest("GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v2/payments/authorizations/", authID), buf)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v2/payments/authorizations/", authID), buf)
auth := &Authorization{}
if err != nil {
@ -24,19 +25,19 @@ 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 /v2/payments/authorizations/ID/capture
func (c *Client) CaptureAuthorization(authID string, paymentCaptureRequest *PaymentCaptureRequest) (*PaymentCaptureResponse, error) {
return c.CaptureAuthorizationWithPaypalRequestId(authID, paymentCaptureRequest, "")
func (c *Client) CaptureAuthorization(ctx context.Context, authID string, paymentCaptureRequest *PaymentCaptureRequest) (*PaymentCaptureResponse, error) {
return c.CaptureAuthorizationWithPaypalRequestId(ctx, authID, paymentCaptureRequest, "")
}
// CaptureAuthorization captures and process an existing authorization with idempotency.
// To use this method, the original payment must have Intent set to "authorize"
// Endpoint: POST /v2/payments/authorizations/ID/capture
func (c *Client) CaptureAuthorizationWithPaypalRequestId(
func (c *Client) CaptureAuthorizationWithPaypalRequestId(ctx context.Context,
authID string,
paymentCaptureRequest *PaymentCaptureRequest,
requestID string,
) (*PaymentCaptureResponse, error) {
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/authorizations/"+authID+"/capture"), paymentCaptureRequest)
req, err := c.NewRequest(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/authorizations/"+authID+"/capture"), paymentCaptureRequest)
paymentCaptureResponse := &PaymentCaptureResponse{}
if err != nil {
@ -53,9 +54,9 @@ func (c *Client) CaptureAuthorizationWithPaypalRequestId(
// VoidAuthorization voids a previously authorized payment
// Endpoint: POST /v2/payments/authorizations/ID/void
func (c *Client) VoidAuthorization(authID string) (*Authorization, error) {
func (c *Client) VoidAuthorization(ctx context.Context, authID string) (*Authorization, error) {
buf := bytes.NewBuffer([]byte(""))
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/authorizations/"+authID+"/void"), buf)
req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/authorizations/"+authID+"/void"), buf)
auth := &Authorization{}
if err != nil {
@ -69,9 +70,9 @@ func (c *Client) VoidAuthorization(authID string) (*Authorization, error) {
// ReauthorizeAuthorization reauthorize a Paypal account payment.
// PayPal recommends to reauthorize payment after ~3 days
// Endpoint: POST /v2/payments/authorizations/ID/reauthorize
func (c *Client) ReauthorizeAuthorization(authID string, a *Amount) (*Authorization, error) {
func (c *Client) ReauthorizeAuthorization(ctx context.Context, 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, "/v2/payments/authorizations/"+authID+"/reauthorize"), buf)
req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/authorizations/"+authID+"/reauthorize"), buf)
auth := &Authorization{}
if err != nil {

View File

@ -1,6 +1,7 @@
package paypal
import (
"context"
"errors"
"fmt"
"net/http"
@ -43,8 +44,8 @@ type (
// CreateBillingPlan creates a billing plan in Paypal
// Endpoint: POST /v1/payments/billing-plans
func (c *Client) CreateBillingPlan(plan BillingPlan) (*CreateBillingResp, error) {
req, err := c.NewRequest(http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-plans"), plan)
func (c *Client) CreateBillingPlan(ctx context.Context, plan BillingPlan) (*CreateBillingResp, error) {
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-plans"), plan)
response := &CreateBillingResp{}
if err != nil {
return response, err
@ -55,7 +56,7 @@ func (c *Client) CreateBillingPlan(plan BillingPlan) (*CreateBillingResp, error)
// UpdateBillingPlan updates values inside a billing plan
// Endpoint: PATCH /v1/payments/billing-plans
func (c *Client) UpdateBillingPlan(planId string, pathValues map[string]map[string]interface{}) error {
func (c *Client) UpdateBillingPlan(ctx context.Context, planId string, pathValues map[string]map[string]interface{}) error {
patchData := []Patch{}
for path, data := range pathValues {
patchData = append(patchData, Patch{
@ -64,8 +65,8 @@ func (c *Client) UpdateBillingPlan(planId string, pathValues map[string]map[stri
Value: data,
})
}
req, err := c.NewRequest(http.MethodPatch, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/payments/billing-plans/", planId), patchData)
req, err := c.NewRequest(ctx, http.MethodPatch, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/payments/billing-plans/", planId), patchData)
if err != nil {
return err
}
@ -76,21 +77,21 @@ func (c *Client) UpdateBillingPlan(planId string, pathValues map[string]map[stri
// ActivatePlan activates a billing plan
// By default, a new plan is not activated
// Endpoint: PATCH /v1/payments/billing-plans/
func (c *Client) ActivatePlan(planID string) error {
return c.UpdateBillingPlan(planID, map[string]map[string]interface{}{
func (c *Client) ActivatePlan(ctx context.Context, planID string) error {
return c.UpdateBillingPlan(ctx, planID, map[string]map[string]interface{}{
"/": {"state": BillingPlanStatusActive},
})
}
// CreateBillingAgreement creates an agreement for specified plan
// Endpoint: POST /v1/payments/billing-agreements
func (c *Client) CreateBillingAgreement(a BillingAgreement) (*CreateAgreementResp, error) {
func (c *Client) CreateBillingAgreement(ctx context.Context, 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(http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-agreements"), a)
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-agreements"), a)
response := &CreateAgreementResp{}
if err != nil {
return response, err
@ -101,8 +102,8 @@ 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
func (c *Client) ExecuteApprovedAgreement(token string) (*ExecuteAgreementResponse, error) {
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/v1/payments/billing-agreements/%s/agreement-execute", c.APIBase, token), nil)
func (c *Client) ExecuteApprovedAgreement(ctx context.Context, token string) (*ExecuteAgreementResponse, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/v1/payments/billing-agreements/%s/agreement-execute", c.APIBase, token), nil)
response := &ExecuteAgreementResponse{}
if err != nil {
@ -125,8 +126,8 @@ func (c *Client) ExecuteApprovedAgreement(token string) (*ExecuteAgreementRespon
// ListBillingPlans lists billing-plans
// Endpoint: GET /v1/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)
func (c *Client) ListBillingPlans(ctx context.Context, bplp BillingPlanListParams) (*BillingPlanListResp, error) {
req, err := c.NewRequest(ctx, "GET", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-plans"), nil)
response := &BillingPlanListResp{}
if err != nil {
return response, err

View File

@ -2,6 +2,7 @@ package paypal
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
@ -30,9 +31,9 @@ func NewClient(clientID string, secret string, APIBase string) (*Client, error)
// GetAccessToken returns struct of TokenResponse
// No need to call SetAccessToken to apply new access token for current Client
// Endpoint: POST /v1/oauth2/token
func (c *Client) GetAccessToken() (*TokenResponse, error) {
func (c *Client) GetAccessToken(ctx context.Context) (*TokenResponse, error) {
buf := bytes.NewBuffer([]byte("grant_type=client_credentials"))
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/oauth2/token"), buf)
req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/oauth2/token"), buf)
if err != nil {
return &TokenResponse{}, err
}
@ -140,7 +141,7 @@ func (c *Client) SendWithAuth(req *http.Request, v interface{}) error {
if c.Token != nil {
if !c.tokenExpiresAt.IsZero() && c.tokenExpiresAt.Sub(time.Now()) < RequestNewTokenBeforeExpiresIn {
// c.Token will be updated in GetAccessToken call
if _, err := c.GetAccessToken(); err != nil {
if _, err := c.GetAccessToken(req.Context()); err != nil {
c.Unlock()
return err
}
@ -164,7 +165,7 @@ func (c *Client) SendWithBasicAuth(req *http.Request, v interface{}) error {
// NewRequest constructs a request
// Convert payload to a JSON
func (c *Client) NewRequest(method, url string, payload interface{}) (*http.Request, error) {
func (c *Client) NewRequest(ctx context.Context, method, url string, payload interface{}) (*http.Request, error) {
var buf io.Reader
if payload != nil {
b, err := json.Marshal(&payload)
@ -173,7 +174,7 @@ func (c *Client) NewRequest(method, url string, payload interface{}) (*http.Requ
}
buf = bytes.NewBuffer(b)
}
return http.NewRequest(method, url, buf)
return http.NewRequestWithContext(ctx, method, url, buf)
}
// log will dump request and response to the log file

View File

@ -1,6 +1,10 @@
package paypal_test
import "github.com/plutov/paypal/v3"
import (
"context"
"github.com/plutov/paypal/v4"
)
func Example() {
// Initialize client
@ -10,7 +14,7 @@ func Example() {
}
// Retrieve access token
_, err = c.GetAccessToken()
_, err = c.GetAccessToken(context.Background())
if err != nil {
panic(err)
}
@ -24,7 +28,7 @@ func ExampleClient_CreateSinglePayout_Venmo() {
}
// Retrieve access token
_, err = c.GetAccessToken()
_, err = c.GetAccessToken(context.Background())
if err != nil {
panic(err)
}
@ -51,5 +55,5 @@ func ExampleClient_CreateSinglePayout_Venmo() {
},
}
c.CreateSinglePayout(payout)
c.CreateSinglePayout(context.Background(), payout)
}

4
go.mod
View File

@ -1,5 +1,5 @@
module github.com/plutov/paypal/v3
module github.com/plutov/paypal/v4
go 1.12
go 1.13
require github.com/stretchr/testify v1.6.0

View File

@ -1,6 +1,7 @@
package paypal
import (
"context"
"fmt"
"net/http"
"net/url"
@ -9,7 +10,7 @@ import (
// GrantNewAccessTokenFromAuthCode - Use this call to grant a new access token, using the previously obtained authorization code.
// Endpoint: POST /v1/identity/openidconnect/tokenservice
func (c *Client) GrantNewAccessTokenFromAuthCode(code, redirectURI string) (*TokenResponse, error) {
func (c *Client) GrantNewAccessTokenFromAuthCode(ctx context.Context, code, redirectURI string) (*TokenResponse, error) {
token := &TokenResponse{}
q := url.Values{}
@ -17,7 +18,7 @@ func (c *Client) GrantNewAccessTokenFromAuthCode(code, redirectURI string) (*Tok
q.Set("code", code)
q.Set("redirect_uri", redirectURI)
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/identity/openidconnect/tokenservice"), strings.NewReader(q.Encode()))
req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/identity/openidconnect/tokenservice"), strings.NewReader(q.Encode()))
if err != nil {
return token, err
}
@ -33,7 +34,7 @@ func (c *Client) GrantNewAccessTokenFromAuthCode(code, redirectURI string) (*Tok
// GrantNewAccessTokenFromRefreshToken - Use this call to grant a new access token, using a refresh token.
// Endpoint: POST /v1/identity/openidconnect/tokenservice
func (c *Client) GrantNewAccessTokenFromRefreshToken(refreshToken string) (*TokenResponse, error) {
func (c *Client) GrantNewAccessTokenFromRefreshToken(ctx context.Context, refreshToken string) (*TokenResponse, error) {
type request struct {
GrantType string `json:"grant_type"`
RefreshToken string `json:"refresh_token"`
@ -41,7 +42,7 @@ func (c *Client) GrantNewAccessTokenFromRefreshToken(refreshToken string) (*Toke
token := &TokenResponse{}
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/identity/openidconnect/tokenservice"), request{GrantType: "refresh_token", RefreshToken: refreshToken})
req, err := c.NewRequest(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/identity/openidconnect/tokenservice"), request{GrantType: "refresh_token", RefreshToken: refreshToken})
if err != nil {
return token, err
}
@ -56,10 +57,10 @@ func (c *Client) GrantNewAccessTokenFromRefreshToken(refreshToken string) (*Toke
// GetUserInfo - Use this call to retrieve user profile attributes.
// Endpoint: GET /v1/identity/openidconnect/userinfo/?schema=<Schema>
// Pass the schema that is used to return as per openidconnect protocol. The only supported schema value is openid.
func (c *Client) GetUserInfo(schema string) (*UserInfo, error) {
func (c *Client) GetUserInfo(ctx context.Context, schema string) (*UserInfo, error) {
u := &UserInfo{}
req, err := http.NewRequest("GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v1/identity/openidconnect/userinfo/?schema=", schema), nil)
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v1/identity/openidconnect/userinfo/?schema=", schema), nil)
if err != nil {
return u, err
}

View File

@ -3,6 +3,7 @@
package paypal
import (
"context"
"testing"
"time"
@ -20,7 +21,7 @@ var testBillingPlan = "" // will be fetched in func TestSubscriptionPlans(t *te
func TestGetAccessToken(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
token, err := c.GetAccessToken()
token, err := c.GetAccessToken(context.Background())
if err != nil {
t.Errorf("Not expected error for GetAccessToken(), got %s", err.Error())
}
@ -31,9 +32,9 @@ func TestGetAccessToken(t *testing.T) {
func TestGetUserInfo(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
c.GetAccessToken(context.Background())
u, err := c.GetUserInfo("openid")
u, err := c.GetUserInfo(context.Background(), "openid")
if u.ID != testUserID || err != nil {
t.Errorf("GetUserInfo must return valid test ID %s, got %s, error: %v", testUserID, u.ID, err)
}
@ -41,7 +42,7 @@ func TestGetUserInfo(t *testing.T) {
func TestCreateVenmoPayout(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
c.GetAccessToken(context.Background())
payout := Payout{
SenderBatchHeader: &SenderBatchHeader{
@ -64,14 +65,14 @@ func TestCreateVenmoPayout(t *testing.T) {
},
}
res, err := c.CreateSinglePayout(payout)
res, err := c.CreateSinglePayout(context.Background(), payout)
assert.NoError(t, err, "should accept venmo wallet")
assert.Greater(t, len(res.Items), 0)
}
func TestCreateSinglePayout(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
c.GetAccessToken(context.Background())
payout := Payout{
SenderBatchHeader: &SenderBatchHeader{
@ -93,19 +94,19 @@ func TestCreateSinglePayout(t *testing.T) {
},
}
c.CreateSinglePayout(payout)
c.CreateSinglePayout(context.Background(), payout)
}
func TestStoreCreditCard(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
c.GetAccessToken(context.Background())
r1, e1 := c.StoreCreditCard(CreditCard{})
r1, e1 := c.StoreCreditCard(context.Background(), CreditCard{})
if e1 == nil || r1 != nil {
t.Errorf("Error is expected for invalid CC")
}
r2, e2 := c.StoreCreditCard(CreditCard{
r2, e2 := c.StoreCreditCard(context.Background(), CreditCard{
Number: "4417119669820331",
Type: "visa",
ExpireMonth: "11",
@ -121,9 +122,9 @@ func TestStoreCreditCard(t *testing.T) {
func TestDeleteCreditCard(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
c.GetAccessToken(context.Background())
e1 := c.DeleteCreditCard("")
e1 := c.DeleteCreditCard(context.Background(), "")
if e1 == nil {
t.Errorf("Error is expected for invalid CC ID")
}
@ -131,9 +132,9 @@ func TestDeleteCreditCard(t *testing.T) {
func TestGetCreditCard(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
c.GetAccessToken(context.Background())
r1, e1 := c.GetCreditCard("BBGGG")
r1, e1 := c.GetCreditCard(context.Background(), "BBGGG")
if e1 == nil || r1 != nil {
t.Errorf("Error is expected for invalid CC, got CC %v", r1)
}
@ -141,14 +142,14 @@ func TestGetCreditCard(t *testing.T) {
func TestGetCreditCards(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
c.GetAccessToken(context.Background())
r1, e1 := c.GetCreditCards(nil)
r1, e1 := c.GetCreditCards(context.Background(), nil)
if e1 != nil || r1 == nil {
t.Errorf("200 code expected. Error: %v", e1)
}
r2, e2 := c.GetCreditCards(&CreditCardsFilter{
r2, e2 := c.GetCreditCards(context.Background(), &CreditCardsFilter{
Page: 2,
PageSize: 7,
})
@ -159,9 +160,9 @@ func TestGetCreditCards(t *testing.T) {
func TestPatchCreditCard(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
c.GetAccessToken(context.Background())
r1, e1 := c.PatchCreditCard(testCardID, nil)
r1, e1 := c.PatchCreditCard(context.Background(), testCardID, nil)
if e1 == nil || r1 != nil {
t.Errorf("Error is expected for empty update info")
}
@ -170,7 +171,7 @@ func TestPatchCreditCard(t *testing.T) {
// Creates, gets, and deletes single webhook
func TestCreateAndGetWebhook(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
c.GetAccessToken(context.Background())
payload := &CreateWebhookRequest{
URL: "https://example.com/paypal_webhooks",
@ -181,17 +182,17 @@ func TestCreateAndGetWebhook(t *testing.T) {
},
}
createdWebhook, err := c.CreateWebhook(payload)
createdWebhook, err := c.CreateWebhook(context.Background(), payload)
if err != nil {
t.Errorf("Webhook couldn't be created, error %v", err)
}
_, err = c.GetWebhook(createdWebhook.ID)
_, err = c.GetWebhook(context.Background(), createdWebhook.ID)
if err != nil {
t.Errorf("An error occurred while getting webhook, error %v", err)
}
err = c.DeleteWebhook(createdWebhook.ID)
err = c.DeleteWebhook(context.Background(), createdWebhook.ID)
if err != nil {
t.Errorf("An error occurred while webhooks deletion, error %v", err)
}
@ -200,7 +201,7 @@ func TestCreateAndGetWebhook(t *testing.T) {
// Creates, updates, and deletes single webhook
func TestCreateAndUpdateWebhook(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
c.GetAccessToken(context.Background())
creationPayload := &CreateWebhookRequest{
URL: "https://example.com/paypal_webhooks",
@ -211,7 +212,7 @@ func TestCreateAndUpdateWebhook(t *testing.T) {
},
}
createdWebhook, err := c.CreateWebhook(creationPayload)
createdWebhook, err := c.CreateWebhook(context.Background(), creationPayload)
if err != nil {
t.Errorf("Webhook couldn't be created, error %v", err)
}
@ -228,12 +229,12 @@ func TestCreateAndUpdateWebhook(t *testing.T) {
},
}
_, err = c.UpdateWebhook(createdWebhook.ID, updatePayload)
_, err = c.UpdateWebhook(context.Background(), createdWebhook.ID, updatePayload)
if err != nil {
t.Errorf("Couldn't update webhook, error %v", err)
}
err = c.DeleteWebhook(createdWebhook.ID)
err = c.DeleteWebhook(context.Background(), createdWebhook.ID)
if err != nil {
t.Errorf("An error occurred while webhooks deletion, error %v", err)
}
@ -241,9 +242,9 @@ func TestCreateAndUpdateWebhook(t *testing.T) {
func TestListWebhooks(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
c.GetAccessToken(context.Background())
_, err := c.ListWebhooks(AncorTypeApplication)
_, err := c.ListWebhooks(context.Background(), AncorTypeApplication)
if err != nil {
t.Errorf("Cannot registered list webhooks, error %v", err)
}
@ -251,7 +252,7 @@ func TestListWebhooks(t *testing.T) {
func TestProduct(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
c.GetAccessToken(context.Background())
//create a product
productData := Product{
@ -263,7 +264,7 @@ func TestProduct(t *testing.T) {
HomeUrl: "https://example.com",
}
productCreateResponse, err := c.CreateProduct(productData)
productCreateResponse, err := c.CreateProduct(context.Background(), productData)
assert.Equal(t, nil, err)
testProductId = productCreateResponse.ID
@ -272,23 +273,23 @@ func TestProduct(t *testing.T) {
productData.ID = productCreateResponse.ID
productData.Description = "Updated product"
err = c.UpdateProduct(productData)
err = c.UpdateProduct(context.Background(), productData)
assert.Equal(t, nil, err)
//get product data
productFetched, err := c.GetProduct(productData.ID)
productFetched, err := c.GetProduct(context.Background(), productData.ID)
assert.Equal(t, nil, err)
assert.Equal(t, productFetched.Description, "Updated product")
//test that lising products have more than one product
productList, err := c.ListProducts(nil)
productList, err := c.ListProducts(context.Background(), nil)
assert.Equal(t, nil, err)
assert.NotEqual(t, len(productList.Products), 0)
}
func TestSubscriptionPlans(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
c.GetAccessToken(context.Background())
//create a product
newSubscriptionPlan := SubscriptionPlan{
@ -330,35 +331,35 @@ func TestSubscriptionPlans(t *testing.T) {
}
//test create new plan
planCreateResponse, err := c.CreateSubscriptionPlan(newSubscriptionPlan)
planCreateResponse, err := c.CreateSubscriptionPlan(context.Background(), newSubscriptionPlan)
assert.Equal(t, nil, err)
testBillingPlan = planCreateResponse.ID // for next test
//test update the newly created plan
newSubscriptionPlan.ID = planCreateResponse.ID
newSubscriptionPlan.Description = "updated description"
err = c.UpdateSubscriptionPlan(newSubscriptionPlan)
err = c.UpdateSubscriptionPlan(context.Background(), newSubscriptionPlan)
assert.Equal(t, nil, err)
//test get plan information
existingPlan, err := c.GetSubscriptionPlan(newSubscriptionPlan.ID)
existingPlan, err := c.GetSubscriptionPlan(context.Background(), newSubscriptionPlan.ID)
assert.Equal(t, nil, err)
assert.Equal(t, newSubscriptionPlan.Description, existingPlan.Description)
//test activate plan
err = c.ActivateSubscriptionPlan(newSubscriptionPlan.ID)
err = c.ActivateSubscriptionPlan(context.Background(), newSubscriptionPlan.ID)
assert.Equal(t, nil, err)
//test deactivate plan
err = c.DeactivateSubscriptionPlans(newSubscriptionPlan.ID)
err = c.DeactivateSubscriptionPlans(context.Background(), newSubscriptionPlan.ID)
assert.Equal(t, nil, err)
//reactivate this plan for next next (subscription)
err = c.ActivateSubscriptionPlan(newSubscriptionPlan.ID)
err = c.ActivateSubscriptionPlan(context.Background(), newSubscriptionPlan.ID)
assert.Equal(t, nil, err)
//test upadte plan pricing
err = c.UpdateSubscriptionPlanPricing(newSubscriptionPlan.ID, []PricingSchemeUpdate{
err = c.UpdateSubscriptionPlanPricing(context.Background(), newSubscriptionPlan.ID, []PricingSchemeUpdate{
{
BillingCycleSequence: 1,
PricingScheme: PricingScheme{
@ -375,7 +376,7 @@ func TestSubscriptionPlans(t *testing.T) {
assert.Equal(t, nil, err)
//test update pricing scheme
updatedPricingPlan, err := c.GetSubscriptionPlan(newSubscriptionPlan.ID)
updatedPricingPlan, err := c.GetSubscriptionPlan(context.Background(), newSubscriptionPlan.ID)
assert.Equal(t, nil, err)
assert.Equal(t, "6.0", updatedPricingPlan.BillingCycles[0].PricingScheme.FixedPrice.Value)
@ -383,19 +384,19 @@ func TestSubscriptionPlans(t *testing.T) {
func TestSubscription(t *testing.T) {
c, _ := NewClient(testClientID, testSecret, APIBaseSandBox)
c.GetAccessToken()
c.GetAccessToken(context.Background())
newSubscription := SubscriptionBase{
PlanID: testBillingPlan,
}
//create new subscription
newSubResponse, err := c.CreateSubscription(newSubscription)
newSubResponse, err := c.CreateSubscription(context.Background(), newSubscription)
assert.Equal(t, nil, err)
assert.NotEqual(t, "", newSubResponse.ID)
//get subscription details
subDetails, err := c.GetSubscriptionDetails(newSubResponse.ID)
subDetails, err := c.GetSubscriptionDetails(context.Background(), newSubResponse.ID)
assert.Equal(t, nil, err)
assert.NotEqual(t, "", subDetails.ID)

View File

@ -1,13 +1,16 @@
package paypal
import "fmt"
import (
"context"
"fmt"
)
// GetOrder retrieves order by ID
// Endpoint: GET /v2/checkout/orders/ID
func (c *Client) GetOrder(orderID string) (*Order, error) {
func (c *Client) GetOrder(ctx context.Context, orderID string) (*Order, error) {
order := &Order{}
req, err := c.NewRequest("GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v2/checkout/orders/", orderID), nil)
req, err := c.NewRequest(ctx, "GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v2/checkout/orders/", orderID), nil)
if err != nil {
return order, err
}
@ -21,7 +24,7 @@ func (c *Client) GetOrder(orderID string) (*Order, error) {
// CreateOrder - Use this call to create an order
// Endpoint: POST /v2/checkout/orders
func (c *Client) CreateOrder(intent string, purchaseUnits []PurchaseUnitRequest, payer *CreateOrderPayer, appContext *ApplicationContext) (*Order, error) {
func (c *Client) CreateOrder(ctx context.Context, intent string, purchaseUnits []PurchaseUnitRequest, payer *CreateOrderPayer, appContext *ApplicationContext) (*Order, error) {
type createOrderRequest struct {
Intent string `json:"intent"`
Payer *CreateOrderPayer `json:"payer,omitempty"`
@ -31,7 +34,7 @@ func (c *Client) CreateOrder(intent string, purchaseUnits []PurchaseUnitRequest,
order := &Order{}
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/checkout/orders"), createOrderRequest{Intent: intent, PurchaseUnits: purchaseUnits, Payer: payer, ApplicationContext: appContext})
req, err := c.NewRequest(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/checkout/orders"), createOrderRequest{Intent: intent, PurchaseUnits: purchaseUnits, Payer: payer, ApplicationContext: appContext})
if err != nil {
return order, err
}
@ -45,10 +48,10 @@ func (c *Client) CreateOrder(intent string, purchaseUnits []PurchaseUnitRequest,
// UpdateOrder updates the order by ID
// Endpoint: PATCH /v2/checkout/orders/ID
func (c *Client) UpdateOrder(orderID string, purchaseUnits []PurchaseUnitRequest) (*Order, error) {
func (c *Client) UpdateOrder(ctx context.Context, orderID string, purchaseUnits []PurchaseUnitRequest) (*Order, error) {
order := &Order{}
req, err := c.NewRequest("PATCH", fmt.Sprintf("%s%s%s", c.APIBase, "/v2/checkout/orders/", orderID), purchaseUnits)
req, err := c.NewRequest(ctx, "PATCH", fmt.Sprintf("%s%s%s", c.APIBase, "/v2/checkout/orders/", orderID), purchaseUnits)
if err != nil {
return order, err
}
@ -62,10 +65,10 @@ func (c *Client) UpdateOrder(orderID string, purchaseUnits []PurchaseUnitRequest
// AuthorizeOrder - https://developer.paypal.com/docs/api/orders/v2/#orders_authorize
// Endpoint: POST /v2/checkout/orders/ID/authorize
func (c *Client) AuthorizeOrder(orderID string, authorizeOrderRequest AuthorizeOrderRequest) (*Authorization, error) {
func (c *Client) AuthorizeOrder(ctx context.Context, orderID string, authorizeOrderRequest AuthorizeOrderRequest) (*Authorization, error) {
auth := &Authorization{}
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/checkout/orders/"+orderID+"/authorize"), authorizeOrderRequest)
req, err := c.NewRequest(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/checkout/orders/"+orderID+"/authorize"), authorizeOrderRequest)
if err != nil {
return auth, err
}
@ -79,14 +82,14 @@ func (c *Client) AuthorizeOrder(orderID string, authorizeOrderRequest AuthorizeO
// CaptureOrder - https://developer.paypal.com/docs/api/orders/v2/#orders_capture
// Endpoint: POST /v2/checkout/orders/ID/capture
func (c *Client) CaptureOrder(orderID string, captureOrderRequest CaptureOrderRequest) (*CaptureOrderResponse, error) {
return c.CaptureOrderWithPaypalRequestId(orderID, captureOrderRequest, "")
func (c *Client) CaptureOrder(ctx context.Context, orderID string, captureOrderRequest CaptureOrderRequest) (*CaptureOrderResponse, error) {
return c.CaptureOrderWithPaypalRequestId(ctx, orderID, captureOrderRequest, "")
}
// CaptureOrder with idempotency - https://developer.paypal.com/docs/api/orders/v2/#orders_capture
// Endpoint: POST /v2/checkout/orders/ID/capture
// https://developer.paypal.com/docs/api/reference/api-requests/#http-request-headers
func (c *Client) CaptureOrderWithPaypalRequestId(
func (c *Client) CaptureOrderWithPaypalRequestId(ctx context.Context,
orderID string,
captureOrderRequest CaptureOrderRequest,
requestID string,
@ -94,7 +97,7 @@ func (c *Client) CaptureOrderWithPaypalRequestId(
capture := &CaptureOrderResponse{}
c.SetReturnRepresentation()
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/checkout/orders/"+orderID+"/capture"), captureOrderRequest)
req, err := c.NewRequest(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/checkout/orders/"+orderID+"/capture"), captureOrderRequest)
if err != nil {
return capture, err
}
@ -112,20 +115,20 @@ func (c *Client) CaptureOrderWithPaypalRequestId(
// RefundCapture - https://developer.paypal.com/docs/api/payments/v2/#captures_refund
// Endpoint: POST /v2/payments/captures/ID/refund
func (c *Client) RefundCapture(captureID string, refundCaptureRequest RefundCaptureRequest) (*RefundResponse, error) {
return c.RefundCaptureWithPaypalRequestId(captureID, refundCaptureRequest, "")
func (c *Client) RefundCapture(ctx context.Context, captureID string, refundCaptureRequest RefundCaptureRequest) (*RefundResponse, error) {
return c.RefundCaptureWithPaypalRequestId(ctx, captureID, refundCaptureRequest, "")
}
// RefundCapture with idempotency - https://developer.paypal.com/docs/api/payments/v2/#captures_refund
// Endpoint: POST /v2/payments/captures/ID/refund
func (c *Client) RefundCaptureWithPaypalRequestId(
func (c *Client) RefundCaptureWithPaypalRequestId(ctx context.Context,
captureID string,
refundCaptureRequest RefundCaptureRequest,
requestID string,
) (*RefundResponse, error) {
refund := &RefundResponse{}
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/captures/"+captureID+"/refund"), refundCaptureRequest)
req, err := c.NewRequest(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/captures/"+captureID+"/refund"), refundCaptureRequest)
if err != nil {
return refund, err
}

View File

@ -1,14 +1,15 @@
package paypal
import (
"context"
"fmt"
)
// CreateSinglePayout submits a payout with an asynchronous API call, which immediately returns the results of a PayPal payment.
// For email payout set RecipientType: "EMAIL" and receiver email into Receiver
// Endpoint: POST /v1/payments/payouts
func (c *Client) CreateSinglePayout(p Payout) (*PayoutResponse, error) {
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/payouts"), p)
func (c *Client) CreateSinglePayout(ctx context.Context, p Payout) (*PayoutResponse, error) {
req, err := c.NewRequest(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/payouts"), p)
response := &PayoutResponse{}
if err != nil {
@ -25,8 +26,8 @@ func (c *Client) CreateSinglePayout(p Payout) (*PayoutResponse, error) {
// GetPayout shows the latest status of a batch payout along with the transaction status and other data for individual items.
// Also, returns IDs for the individual payout items. You can use these item IDs in other calls.
// Endpoint: GET /v1/payments/payouts/ID
func (c *Client) GetPayout(payoutBatchID string) (*PayoutResponse, error) {
req, err := c.NewRequest("GET", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/payouts/"+payoutBatchID), nil)
func (c *Client) GetPayout(ctx context.Context, payoutBatchID string) (*PayoutResponse, error) {
req, err := c.NewRequest(ctx, "GET", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/payouts/"+payoutBatchID), nil)
response := &PayoutResponse{}
if err != nil {
@ -43,8 +44,8 @@ func (c *Client) GetPayout(payoutBatchID string) (*PayoutResponse, error) {
// GetPayoutItem shows the details for a payout item.
// Use this call to review the current status of a previously unclaimed, or pending, payout item.
// Endpoint: GET /v1/payments/payouts-item/ID
func (c *Client) GetPayoutItem(payoutItemID string) (*PayoutItemResponse, error) {
req, err := c.NewRequest("GET", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/payouts-item/"+payoutItemID), nil)
func (c *Client) GetPayoutItem(ctx context.Context, payoutItemID string) (*PayoutItemResponse, error) {
req, err := c.NewRequest(ctx, "GET", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/payouts-item/"+payoutItemID), nil)
response := &PayoutItemResponse{}
if err != nil {
@ -61,8 +62,8 @@ func (c *Client) GetPayoutItem(payoutItemID string) (*PayoutItemResponse, error)
// CancelPayoutItem cancels an unclaimed Payout Item. If no one claims the unclaimed item within 30 days,
// the funds are automatically returned to the sender. Use this call to cancel the unclaimed item before the automatic 30-day refund.
// Endpoint: POST /v1/payments/payouts-item/ID/cancel
func (c *Client) CancelPayoutItem(payoutItemID string) (*PayoutItemResponse, error) {
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/payouts-item/"+payoutItemID+"/cancel"), nil)
func (c *Client) CancelPayoutItem(ctx context.Context, payoutItemID string) (*PayoutItemResponse, error) {
req, err := c.NewRequest(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/payouts-item/"+payoutItemID+"/cancel"), nil)
response := &PayoutItemResponse{}
if err != nil {

View File

@ -1,6 +1,7 @@
package paypal
import (
"context"
"fmt"
"net/http"
)
@ -60,8 +61,8 @@ func (self *Product) GetUpdatePatch() []Patch {
// CreateProduct creates a product
// Doc: https://developer.paypal.com/docs/api/catalog-products/v1/#products_create
// Endpoint: POST /v1/catalogs/products
func (c *Client) CreateProduct(product Product) (*CreateProductResponse, error) {
req, err := c.NewRequest(http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/catalogs/products"), product)
func (c *Client) CreateProduct(ctx context.Context, product Product) (*CreateProductResponse, error) {
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/catalogs/products"), product)
response := &CreateProductResponse{}
if err != nil {
return response, err
@ -73,8 +74,8 @@ func (c *Client) CreateProduct(product Product) (*CreateProductResponse, error)
// UpdateProduct. updates a product information
// Doc: https://developer.paypal.com/docs/api/catalog-products/v1/#products_patch
// Endpoint: PATCH /v1/catalogs/products/:product_id
func (c *Client) UpdateProduct(product Product) error {
req, err := c.NewRequest(http.MethodPatch, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/catalogs/products/", product.ID), product.GetUpdatePatch())
func (c *Client) UpdateProduct(ctx context.Context, product Product) error {
req, err := c.NewRequest(ctx, http.MethodPatch, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/catalogs/products/", product.ID), product.GetUpdatePatch())
if err != nil {
return err
}
@ -85,8 +86,8 @@ func (c *Client) UpdateProduct(product Product) error {
// Get product details
// Doc: https://developer.paypal.com/docs/api/catalog-products/v1/#products_get
// Endpoint: GET /v1/catalogs/products/:product_id
func (c *Client) GetProduct(productId string) (*Product, error) {
req, err := c.NewRequest(http.MethodGet, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/catalogs/products/", productId), nil)
func (c *Client) GetProduct(ctx context.Context, productId string) (*Product, error) {
req, err := c.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/catalogs/products/", productId), nil)
response := &Product{}
if err != nil {
return response, err
@ -98,8 +99,8 @@ func (c *Client) GetProduct(productId string) (*Product, error) {
// List all products
// Doc: https://developer.paypal.com/docs/api/catalog-products/v1/#products_list
// Endpoint: GET /v1/catalogs/products
func (c *Client) ListProducts(params *ProductListParameters) (*ListProductsResponse, error) {
req, err := c.NewRequest(http.MethodGet, fmt.Sprintf("%s%s", c.APIBase, "/v1/catalogs/products"), nil)
func (c *Client) ListProducts(ctx context.Context, params *ProductListParameters) (*ListProductsResponse, error) {
req, err := c.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s%s", c.APIBase, "/v1/catalogs/products"), nil)
response := &ListProductsResponse{}
if err != nil {
return response, err

17
sale.go
View File

@ -1,15 +1,18 @@
package paypal
import "fmt"
import (
"context"
"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
func (c *Client) GetSale(saleID string) (*Sale, error) {
func (c *Client) GetSale(ctx context.Context, 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(ctx, "GET", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/sale/"+saleID), nil)
if err != nil {
return sale, err
}
@ -24,14 +27,14 @@ 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
func (c *Client) RefundSale(saleID string, a *Amount) (*Refund, error) {
func (c *Client) RefundSale(ctx context.Context, saleID string, a *Amount) (*Refund, error) {
type refundRequest struct {
Amount *Amount `json:"amount"`
}
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(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/sale/"+saleID+"/refund"), &refundRequest{Amount: a})
if err != nil {
return refund, err
}
@ -46,10 +49,10 @@ 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 /v2/payments/refund/ID
func (c *Client) GetRefund(refundID string) (*Refund, error) {
func (c *Client) GetRefund(ctx context.Context, refundID string) (*Refund, error) {
refund := &Refund{}
req, err := c.NewRequest("GET", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/refund/"+refundID), nil)
req, err := c.NewRequest(ctx, "GET", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/refund/"+refundID), nil)
if err != nil {
return refund, err
}

View File

@ -1,6 +1,7 @@
package paypal
import (
"context"
"fmt"
"net/http"
"time"
@ -88,8 +89,8 @@ func (self *Subscription) GetUpdatePatch() []Patch {
// CreateSubscriptionPlan creates a subscriptionPlan
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_create
// Endpoint: POST /v1/billing/subscriptions
func (c *Client) CreateSubscription(newSubscription SubscriptionBase) (*SubscriptionDetailResp, error) {
req, err := c.NewRequest(http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/billing/subscriptions"), newSubscription)
func (c *Client) CreateSubscription(ctx context.Context, newSubscription SubscriptionBase) (*SubscriptionDetailResp, error) {
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/billing/subscriptions"), newSubscription)
req.Header.Add("Prefer", "return=representation")
response := &SubscriptionDetailResp{}
if err != nil {
@ -102,8 +103,8 @@ func (c *Client) CreateSubscription(newSubscription SubscriptionBase) (*Subscrip
// UpdateSubscriptionPlan. updates a plan
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_patch
// Endpoint: PATCH /v1/billing/subscriptions/:subscription_id
func (c *Client) UpdateSubscription(updatedSubscription Subscription) error {
req, err := c.NewRequest(http.MethodPatch, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/billing/subscriptions/", updatedSubscription.ID), updatedSubscription.GetUpdatePatch())
func (c *Client) UpdateSubscription(ctx context.Context, updatedSubscription Subscription) error {
req, err := c.NewRequest(ctx, http.MethodPatch, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/billing/subscriptions/", updatedSubscription.ID), updatedSubscription.GetUpdatePatch())
if err != nil {
return err
}
@ -113,8 +114,8 @@ func (c *Client) UpdateSubscription(updatedSubscription Subscription) error {
// GetSubscriptionDetails shows details for a subscription, by ID.
// Endpoint: GET /v1/billing/subscriptions/
func (c *Client) GetSubscriptionDetails(subscriptionID string) (*SubscriptionDetailResp, error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/v1/billing/subscriptions/%s", c.APIBase, subscriptionID), nil)
func (c *Client) GetSubscriptionDetails(ctx context.Context, subscriptionID string) (*SubscriptionDetailResp, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/v1/billing/subscriptions/%s", c.APIBase, subscriptionID), nil)
response := &SubscriptionDetailResp{}
if err != nil {
return response, err
@ -126,8 +127,8 @@ func (c *Client) GetSubscriptionDetails(subscriptionID string) (*SubscriptionDet
// Activates the subscription.
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_activate
// Endpoint: POST /v1/billing/subscriptions/{id}/activate
func (c *Client) ActivateSubscription(subscriptionId, activateReason string) error {
req, err := c.NewRequest(http.MethodPost, fmt.Sprintf("%s/v1/billing/subscriptions/%s/activate", c.APIBase, subscriptionId), map[string]string{"reason": activateReason})
func (c *Client) ActivateSubscription(ctx context.Context, subscriptionId, activateReason string) error {
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s/v1/billing/subscriptions/%s/activate", c.APIBase, subscriptionId), map[string]string{"reason": activateReason})
if err != nil {
return err
}
@ -138,8 +139,8 @@ func (c *Client) ActivateSubscription(subscriptionId, activateReason string) err
// Cancels the subscription.
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_cancel
// Endpoint: POST /v1/billing/subscriptions/{id}/cancel
func (c *Client) CancelSubscription(subscriptionId, cancelReason string) error {
req, err := c.NewRequest(http.MethodPost, fmt.Sprintf("%s/v1/billing/subscriptions/%s/cancel", c.APIBase, subscriptionId), map[string]string{"reason": cancelReason})
func (c *Client) CancelSubscription(ctx context.Context, subscriptionId, cancelReason string) error {
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s/v1/billing/subscriptions/%s/cancel", c.APIBase, subscriptionId), map[string]string{"reason": cancelReason})
if err != nil {
return err
}
@ -150,8 +151,8 @@ func (c *Client) CancelSubscription(subscriptionId, cancelReason string) error {
// Captures an authorized payment from the subscriber on the subscription.
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_capture
// Endpoint: POST /v1/billing/subscriptions/{id}/capture
func (c *Client) CaptureSubscription(subscriptionId string, request CaptureReqeust) (*SubscriptionCaptureResponse, error) {
req, err := c.NewRequest(http.MethodPost, fmt.Sprintf("%s/v1/billing/subscriptions/%s/capture", c.APIBase, subscriptionId), request)
func (c *Client) CaptureSubscription(ctx context.Context, subscriptionId string, request CaptureReqeust) (*SubscriptionCaptureResponse, error) {
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s/v1/billing/subscriptions/%s/capture", c.APIBase, subscriptionId), request)
response := &SubscriptionCaptureResponse{}
if err != nil {
return response, err
@ -163,8 +164,8 @@ func (c *Client) CaptureSubscription(subscriptionId string, request CaptureReqeu
// Suspends the subscription.
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_suspend
// Endpoint: POST /v1/billing/subscriptions/{id}/suspend
func (c *Client) SuspendSubscription(subscriptionId, reason string) error {
req, err := c.NewRequest(http.MethodPost, fmt.Sprintf("%s/v1/billing/subscriptions/%s/suspend", c.APIBase, subscriptionId), map[string]string{"reason": reason})
func (c *Client) SuspendSubscription(ctx context.Context, subscriptionId, reason string) error {
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s/v1/billing/subscriptions/%s/suspend", c.APIBase, subscriptionId), map[string]string{"reason": reason})
if err != nil {
return err
}
@ -175,10 +176,10 @@ func (c *Client) SuspendSubscription(subscriptionId, reason string) error {
// Lists transactions for a subscription.
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_transactions
// Endpoint: GET /v1/billing/subscriptions/{id}/transactions
func (c *Client) GetSubscriptionTransactions(requestParams SubscriptionTransactionsParams) (*SubscriptionTransactionsResponse, error) {
func (c *Client) GetSubscriptionTransactions(ctx context.Context, requestParams SubscriptionTransactionsParams) (*SubscriptionTransactionsResponse, error) {
startTime := requestParams.StartTime.Format("2006-01-02T15:04:05Z")
endTime := requestParams.EndTime.Format("2006-01-02T15:04:05Z")
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/v1/billing/subscriptions/%s/transactions?start_time=%s&end_time=%s", c.APIBase, requestParams.SubscriptionId, startTime, endTime), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/v1/billing/subscriptions/%s/transactions?start_time=%s&end_time=%s", c.APIBase, requestParams.SubscriptionId, startTime, endTime), nil)
response := &SubscriptionTransactionsResponse{}
if err != nil {
return response, err
@ -191,8 +192,8 @@ func (c *Client) GetSubscriptionTransactions(requestParams SubscriptionTransacti
// Revise plan or quantity of subscription
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_revise
// Endpoint: POST /v1/billing/subscriptions/{id}/revise
func (c *Client) ReviseSubscription(subscriptionId string, reviseSubscription SubscriptionBase) (*SubscriptionDetailResp, error) {
req, err := c.NewRequest(http.MethodPost, fmt.Sprintf("%s/v1/billing/subscriptions/%s/revise", c.APIBase, subscriptionId), reviseSubscription)
func (c *Client) ReviseSubscription(ctx context.Context, subscriptionId string, reviseSubscription SubscriptionBase) (*SubscriptionDetailResp, error) {
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s/v1/billing/subscriptions/%s/revise", c.APIBase, subscriptionId), reviseSubscription)
response := &SubscriptionDetailResp{}
if err != nil {
return response, err

View File

@ -1,6 +1,7 @@
package paypal
import (
"context"
"fmt"
"net/http"
"time"
@ -131,8 +132,8 @@ func (self *SubscriptionPlan) GetUpdatePatch() []Patch {
// CreateSubscriptionPlan creates a subscriptionPlan
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#plans_create
// Endpoint: POST /v1/billing/plans
func (c *Client) CreateSubscriptionPlan(newPlan SubscriptionPlan) (*CreateSubscriptionPlanResponse, error) {
req, err := c.NewRequest(http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/billing/plans"), newPlan)
func (c *Client) CreateSubscriptionPlan(ctx context.Context, newPlan SubscriptionPlan) (*CreateSubscriptionPlanResponse, error) {
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/billing/plans"), newPlan)
response := &CreateSubscriptionPlanResponse{}
if err != nil {
return response, err
@ -144,8 +145,8 @@ func (c *Client) CreateSubscriptionPlan(newPlan SubscriptionPlan) (*CreateSubscr
// UpdateSubscriptionPlan. updates a plan
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#plans_patch
// Endpoint: PATCH /v1/billing/plans/:plan_id
func (c *Client) UpdateSubscriptionPlan(updatedPlan SubscriptionPlan) error {
req, err := c.NewRequest(http.MethodPatch, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/billing/plans/", updatedPlan.ID), updatedPlan.GetUpdatePatch())
func (c *Client) UpdateSubscriptionPlan(ctx context.Context, updatedPlan SubscriptionPlan) error {
req, err := c.NewRequest(ctx, http.MethodPatch, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/billing/plans/", updatedPlan.ID), updatedPlan.GetUpdatePatch())
if err != nil {
return err
}
@ -156,8 +157,8 @@ func (c *Client) UpdateSubscriptionPlan(updatedPlan SubscriptionPlan) error {
// UpdateSubscriptionPlan. updates a plan
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#plans_get
// Endpoint: GET /v1/billing/plans/:plan_id
func (c *Client) GetSubscriptionPlan(planId string) (*SubscriptionPlan, error) {
req, err := c.NewRequest(http.MethodGet, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/billing/plans/", planId), nil)
func (c *Client) GetSubscriptionPlan(ctx context.Context, planId string) (*SubscriptionPlan, error) {
req, err := c.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/billing/plans/", planId), nil)
response := &SubscriptionPlan{}
if err != nil {
return response, err
@ -169,8 +170,8 @@ func (c *Client) GetSubscriptionPlan(planId string) (*SubscriptionPlan, error) {
// List all plans
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#plans_list
// Endpoint: GET /v1/billing/plans
func (c *Client) ListSubscriptionPlans(params *SubscriptionPlanListParameters) (*ListSubscriptionPlansResponse, error) {
req, err := c.NewRequest(http.MethodGet, fmt.Sprintf("%s%s", c.APIBase, "/v1/billing/plans"), nil)
func (c *Client) ListSubscriptionPlans(ctx context.Context, params *SubscriptionPlanListParameters) (*ListSubscriptionPlansResponse, error) {
req, err := c.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s%s", c.APIBase, "/v1/billing/plans"), nil)
response := &ListSubscriptionPlansResponse{}
if err != nil {
return response, err
@ -193,8 +194,8 @@ func (c *Client) ListSubscriptionPlans(params *SubscriptionPlanListParameters) (
// Activates a plan
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#plans_activate
// Endpoint: POST /v1/billing/plans/{id}/activate
func (c *Client) ActivateSubscriptionPlan(planId string) error {
req, err := c.NewRequest(http.MethodPost, fmt.Sprintf("%s/v1/billing/plans/%s/activate", c.APIBase, planId), nil)
func (c *Client) ActivateSubscriptionPlan(ctx context.Context, planId string) error {
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s/v1/billing/plans/%s/activate", c.APIBase, planId), nil)
if err != nil {
return err
}
@ -206,8 +207,8 @@ func (c *Client) ActivateSubscriptionPlan(planId string) error {
// Deactivates a plan
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#plans_deactivate
// Endpoint: POST /v1/billing/plans/{id}/deactivate
func (c *Client) DeactivateSubscriptionPlans(planId string) error {
req, err := c.NewRequest(http.MethodPost, fmt.Sprintf("%s/v1/billing/plans/%s/deactivate", c.APIBase, planId), nil)
func (c *Client) DeactivateSubscriptionPlans(ctx context.Context, planId string) error {
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s/v1/billing/plans/%s/deactivate", c.APIBase, planId), nil)
if err != nil {
return err
}
@ -219,8 +220,8 @@ func (c *Client) DeactivateSubscriptionPlans(planId string) error {
// Updates pricing for a plan. For example, you can update a regular billing cycle from $5 per month to $7 per month.
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#plans_update-pricing-schemes
// Endpoint: POST /v1/billing/plans/{id}/update-pricing-schemes
func (c *Client) UpdateSubscriptionPlanPricing(planId string, pricingSchemes []PricingSchemeUpdate) error {
req, err := c.NewRequest(http.MethodPost, fmt.Sprintf("%s/v1/billing/plans/%s/update-pricing-schemes", c.APIBase, planId), PricingSchemeUpdateRequest{
func (c *Client) UpdateSubscriptionPlanPricing(ctx context.Context, planId string, pricingSchemes []PricingSchemeUpdate) error {
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s/v1/billing/plans/%s/update-pricing-schemes", c.APIBase, planId), PricingSchemeUpdateRequest{
Schemes: pricingSchemes,
})
if err != nil {

View File

@ -1,6 +1,7 @@
package paypal
import (
"context"
"fmt"
"strconv"
"time"
@ -35,10 +36,10 @@ type TransactionSearchResponse struct {
// ListTransactions - Use this to search PayPal transactions from the last 31 days.
// Endpoint: GET /v1/reporting/transactions
func (c *Client) ListTransactions(req *TransactionSearchRequest) (*TransactionSearchResponse, error) {
func (c *Client) ListTransactions(ctx context.Context, req *TransactionSearchRequest) (*TransactionSearchResponse, error) {
response := &TransactionSearchResponse{}
r, err := c.NewRequest("GET", fmt.Sprintf("%s%s", c.APIBase, "/v1/reporting/transactions"), nil)
r, err := c.NewRequest(ctx, "GET", fmt.Sprintf("%s%s", c.APIBase, "/v1/reporting/transactions"), nil)
if err != nil {
return nil, err
}

View File

@ -134,11 +134,11 @@ const (
//
// https://developer.paypal.com/docs/api/payments.payouts-batch/v1/#definition-batch_status
const (
BatchStatusDenied string = "DENIED"
BatchStatusPending string = "PENDING"
BatchStatusProcessing string = "PROCESSING"
BatchStatusDenied string = "DENIED"
BatchStatusPending string = "PENDING"
BatchStatusProcessing string = "PROCESSING"
BatchStatusSuccess string = "SUCCESS"
BatchStatusCanceled string = "CANCELED"
BatchStatusCanceled string = "CANCELED"
)
const (

View File

@ -1,6 +1,7 @@
package paypal
import (
"context"
"encoding/json"
"io/ioutil"
"net/http"
@ -590,7 +591,7 @@ func TestCreateWebProfile_valid(t *testing.T) {
},
}
res, err := c.CreateWebProfile(wp)
res, err := c.CreateWebProfile(context.Background(), wp)
if err != nil {
t.Fatal(err)
@ -609,7 +610,7 @@ func TestCreateWebProfile_invalid(t *testing.T) {
wp := WebProfile{}
_, err := c.CreateWebProfile(wp)
_, err := c.CreateWebProfile(context.Background(), wp)
if err == nil {
t.Fatalf("expecting an error got nil")
@ -622,7 +623,7 @@ func TestGetWebProfile_valid(t *testing.T) {
c, _ := NewClient("foo", "bar", ts.URL)
res, err := c.GetWebProfile("XP-CP6S-W9DY-96H8-MVN2")
res, err := c.GetWebProfile(context.Background(), "XP-CP6S-W9DY-96H8-MVN2")
if err != nil {
t.Fatal(err)
@ -643,7 +644,7 @@ func TestGetWebProfile_invalid(t *testing.T) {
c, _ := NewClient("foo", "bar", ts.URL)
_, err := c.GetWebProfile("foobar")
_, err := c.GetWebProfile(context.Background(), "foobar")
if err == nil {
t.Fatalf("expecting an error got nil")
@ -656,7 +657,7 @@ func TestGetWebProfiles(t *testing.T) {
c, _ := NewClient("foo", "bar", ts.URL)
res, err := c.GetWebProfiles()
res, err := c.GetWebProfiles(context.Background())
if err != nil {
t.Fatal(err)
@ -678,7 +679,7 @@ func TestSetWebProfile_valid(t *testing.T) {
Name: "Shop T-Shirt YeowZa!",
}
err := c.SetWebProfile(wp)
err := c.SetWebProfile(context.Background(), wp)
if err != nil {
t.Fatal(err)
@ -696,7 +697,7 @@ func TestSetWebProfile_invalid(t *testing.T) {
ID: "foobar",
}
err := c.SetWebProfile(wp)
err := c.SetWebProfile(context.Background(), wp)
if err == nil {
t.Fatal(err)
@ -704,7 +705,7 @@ func TestSetWebProfile_invalid(t *testing.T) {
wp = WebProfile{}
err = c.SetWebProfile(wp)
err = c.SetWebProfile(context.Background(), wp)
if err == nil {
t.Fatal(err)
@ -722,7 +723,7 @@ func TestDeleteWebProfile_valid(t *testing.T) {
Name: "Shop T-Shirt YeowZa!",
}
err := c.SetWebProfile(wp)
err := c.SetWebProfile(context.Background(), wp)
if err != nil {
t.Fatal(err)
@ -736,7 +737,7 @@ func TestDeleteWebProfile_invalid(t *testing.T) {
c, _ := NewClient("foo", "bar", ts.URL)
err := c.DeleteWebProfile("foobar")
err := c.DeleteWebProfile(context.Background(), "foobar")
if err == nil {
t.Fatal(err)

View File

@ -1,13 +1,14 @@
package paypal
import (
"context"
"fmt"
)
// StoreCreditCard func
// Endpoint: POST /v1/vault/credit-cards
func (c *Client) StoreCreditCard(cc CreditCard) (*CreditCard, error) {
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/vault/credit-cards"), cc)
func (c *Client) StoreCreditCard(ctx context.Context, cc CreditCard) (*CreditCard, error) {
req, err := c.NewRequest(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/vault/credit-cards"), cc)
if err != nil {
return nil, err
}
@ -23,8 +24,8 @@ func (c *Client) StoreCreditCard(cc CreditCard) (*CreditCard, error) {
// DeleteCreditCard func
// Endpoint: DELETE /v1/vault/credit-cards/credit_card_id
func (c *Client) DeleteCreditCard(id string) error {
req, err := c.NewRequest("DELETE", fmt.Sprintf("%s/v1/vault/credit-cards/%s", c.APIBase, id), nil)
func (c *Client) DeleteCreditCard(ctx context.Context, id string) error {
req, err := c.NewRequest(ctx, "DELETE", fmt.Sprintf("%s/v1/vault/credit-cards/%s", c.APIBase, id), nil)
if err != nil {
return err
}
@ -38,8 +39,8 @@ func (c *Client) DeleteCreditCard(id string) error {
// GetCreditCard func
// Endpoint: GET /v1/vault/credit-cards/credit_card_id
func (c *Client) GetCreditCard(id string) (*CreditCard, error) {
req, err := c.NewRequest("GET", fmt.Sprintf("%s/v1/vault/credit-cards/%s", c.APIBase, id), nil)
func (c *Client) GetCreditCard(ctx context.Context, id string) (*CreditCard, error) {
req, err := c.NewRequest(ctx, "GET", fmt.Sprintf("%s/v1/vault/credit-cards/%s", c.APIBase, id), nil)
if err != nil {
return nil, err
}
@ -55,7 +56,7 @@ func (c *Client) GetCreditCard(id string) (*CreditCard, error) {
// GetCreditCards func
// Endpoint: GET /v1/vault/credit-cards
func (c *Client) GetCreditCards(ccf *CreditCardsFilter) (*CreditCards, error) {
func (c *Client) GetCreditCards(ctx context.Context, ccf *CreditCardsFilter) (*CreditCards, error) {
page := 1
if ccf != nil && ccf.Page > 0 {
page = ccf.Page
@ -65,7 +66,7 @@ func (c *Client) GetCreditCards(ccf *CreditCardsFilter) (*CreditCards, error) {
pageSize = ccf.PageSize
}
req, err := c.NewRequest("GET", fmt.Sprintf("%s/v1/vault/credit-cards?page=%d&page_size=%d", c.APIBase, page, pageSize), nil)
req, err := c.NewRequest(ctx, "GET", fmt.Sprintf("%s/v1/vault/credit-cards?page=%d&page_size=%d", c.APIBase, page, pageSize), nil)
if err != nil {
return nil, err
}
@ -81,8 +82,8 @@ func (c *Client) GetCreditCards(ccf *CreditCardsFilter) (*CreditCards, error) {
// PatchCreditCard func
// Endpoint: PATCH /v1/vault/credit-cards/credit_card_id
func (c *Client) PatchCreditCard(id string, ccf []CreditCardField) (*CreditCard, error) {
req, err := c.NewRequest("PATCH", fmt.Sprintf("%s/v1/vault/credit-cards/%s", c.APIBase, id), ccf)
func (c *Client) PatchCreditCard(ctx context.Context, id string, ccf []CreditCardField) (*CreditCard, error) {
req, err := c.NewRequest(ctx, "PATCH", fmt.Sprintf("%s/v1/vault/credit-cards/%s", c.APIBase, id), ccf)
if err != nil {
return nil, err
}

View File

@ -2,6 +2,7 @@ package paypal
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io/ioutil"
@ -10,8 +11,8 @@ import (
// CreateWebhook - Subscribes your webhook listener to events.
// Endpoint: POST /v1/notifications/webhooks
func (c *Client) CreateWebhook(createWebhookRequest *CreateWebhookRequest) (*Webhook, error) {
req, err := c.NewRequest(http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/notifications/webhooks"), createWebhookRequest)
func (c *Client) CreateWebhook(ctx context.Context, createWebhookRequest *CreateWebhookRequest) (*Webhook, error) {
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/notifications/webhooks"), createWebhookRequest)
webhook := &Webhook{}
if err != nil {
return webhook, err
@ -23,8 +24,8 @@ func (c *Client) CreateWebhook(createWebhookRequest *CreateWebhookRequest) (*Web
// GetWebhook - Shows details for a webhook, by ID.
// Endpoint: GET /v1/notifications/webhooks/ID
func (c *Client) GetWebhook(webhookID string) (*Webhook, error) {
req, err := c.NewRequest(http.MethodGet, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/notifications/webhooks/", webhookID), nil)
func (c *Client) GetWebhook(ctx context.Context, webhookID string) (*Webhook, error) {
req, err := c.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/notifications/webhooks/", webhookID), nil)
webhook := &Webhook{}
if err != nil {
return webhook, err
@ -36,8 +37,8 @@ func (c *Client) GetWebhook(webhookID string) (*Webhook, error) {
// UpdateWebhook - Updates a webhook to replace webhook fields with new values.
// Endpoint: PATCH /v1/notifications/webhooks/ID
func (c *Client) UpdateWebhook(webhookID string, fields []WebhookField) (*Webhook, error) {
req, err := c.NewRequest(http.MethodPatch, fmt.Sprintf("%s/v1/notifications/webhooks/%s", c.APIBase, webhookID), fields)
func (c *Client) UpdateWebhook(ctx context.Context, webhookID string, fields []WebhookField) (*Webhook, error) {
req, err := c.NewRequest(ctx, http.MethodPatch, fmt.Sprintf("%s/v1/notifications/webhooks/%s", c.APIBase, webhookID), fields)
webhook := &Webhook{}
if err != nil {
return webhook, err
@ -49,11 +50,11 @@ func (c *Client) UpdateWebhook(webhookID string, fields []WebhookField) (*Webhoo
// ListWebhooks - Lists webhooks for an app.
// Endpoint: GET /v1/notifications/webhooks
func (c *Client) ListWebhooks(anchorType string) (*ListWebhookResponse, error) {
func (c *Client) ListWebhooks(ctx context.Context, anchorType string) (*ListWebhookResponse, error) {
if len(anchorType) == 0 {
anchorType = AncorTypeApplication
}
req, err := c.NewRequest(http.MethodGet, fmt.Sprintf("%s%s", c.APIBase, "/v1/notifications/webhooks"), nil)
req, err := c.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s%s", c.APIBase, "/v1/notifications/webhooks"), nil)
q := req.URL.Query()
q.Add("anchor_type", anchorType)
req.URL.RawQuery = q.Encode()
@ -68,8 +69,8 @@ func (c *Client) ListWebhooks(anchorType string) (*ListWebhookResponse, error) {
// DeleteWebhook - Deletes a webhook, by ID.
// Endpoint: DELETE /v1/notifications/webhooks/ID
func (c *Client) DeleteWebhook(webhookID string) error {
req, err := c.NewRequest(http.MethodDelete, fmt.Sprintf("%s/v1/notifications/webhooks/%s", c.APIBase, webhookID), nil)
func (c *Client) DeleteWebhook(ctx context.Context, webhookID string) error {
req, err := c.NewRequest(ctx, http.MethodDelete, fmt.Sprintf("%s/v1/notifications/webhooks/%s", c.APIBase, webhookID), nil)
if err != nil {
return err
}
@ -80,7 +81,7 @@ func (c *Client) DeleteWebhook(webhookID string) error {
// VerifyWebhookSignature - Use this to verify the signature of a webhook recieved from paypal.
// Endpoint: POST /v1/notifications/verify-webhook-signature
func (c *Client) VerifyWebhookSignature(httpReq *http.Request, webhookID string) (*VerifyWebhookResponse, error) {
func (c *Client) VerifyWebhookSignature(ctx context.Context, httpReq *http.Request, webhookID string) (*VerifyWebhookResponse, error) {
type verifyWebhookSignatureRequest struct {
AuthAlgo string `json:"auth_algo,omitempty"`
CertURL string `json:"cert_url,omitempty"`
@ -111,7 +112,7 @@ func (c *Client) VerifyWebhookSignature(httpReq *http.Request, webhookID string)
response := &VerifyWebhookResponse{}
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/notifications/verify-webhook-signature"), verifyRequest)
req, err := c.NewRequest(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/notifications/verify-webhook-signature"), verifyRequest)
if err != nil {
return nil, err
}

View File

@ -1,6 +1,7 @@
package paypal
import (
"context"
"fmt"
"net/http"
)
@ -10,9 +11,9 @@ import (
// Allows for the customisation of the payment experience
//
// Endpoint: POST /v1/payment-experience/web-profiles
func (c *Client) CreateWebProfile(wp WebProfile) (*WebProfile, error) {
func (c *Client) CreateWebProfile(ctx context.Context, wp WebProfile) (*WebProfile, error) {
url := fmt.Sprintf("%s%s", c.APIBase, "/v1/payment-experience/web-profiles")
req, err := c.NewRequest("POST", url, wp)
req, err := c.NewRequest(ctx, "POST", url, wp)
response := &WebProfile{}
if err != nil {
@ -29,11 +30,11 @@ func (c *Client) CreateWebProfile(wp WebProfile) (*WebProfile, error) {
// GetWebProfile gets an exists payment experience from Paypal
//
// Endpoint: GET /v1/payment-experience/web-profiles/<profile-id>
func (c *Client) GetWebProfile(profileID string) (*WebProfile, error) {
func (c *Client) GetWebProfile(ctx context.Context, profileID string) (*WebProfile, error) {
var wp WebProfile
url := fmt.Sprintf("%s%s%s", c.APIBase, "/v1/payment-experience/web-profiles/", profileID)
req, err := http.NewRequest("GET", url, nil)
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return &wp, err
@ -53,11 +54,11 @@ func (c *Client) GetWebProfile(profileID string) (*WebProfile, error) {
// GetWebProfiles retreieves web experience profiles from Paypal
//
// Endpoint: GET /v1/payment-experience/web-profiles
func (c *Client) GetWebProfiles() ([]WebProfile, error) {
func (c *Client) GetWebProfiles(ctx context.Context) ([]WebProfile, error) {
var wps []WebProfile
url := fmt.Sprintf("%s%s", c.APIBase, "/v1/payment-experience/web-profiles")
req, err := http.NewRequest("GET", url, nil)
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return wps, err
@ -73,7 +74,7 @@ func (c *Client) GetWebProfiles() ([]WebProfile, error) {
// SetWebProfile sets a web experience profile in Paypal with given id
//
// Endpoint: PUT /v1/payment-experience/web-profiles
func (c *Client) SetWebProfile(wp WebProfile) error {
func (c *Client) SetWebProfile(ctx context.Context, wp WebProfile) error {
if wp.ID == "" {
return fmt.Errorf("paypal: no ID specified for WebProfile")
@ -81,7 +82,7 @@ func (c *Client) SetWebProfile(wp WebProfile) error {
url := fmt.Sprintf("%s%s%s", c.APIBase, "/v1/payment-experience/web-profiles/", wp.ID)
req, err := c.NewRequest("PUT", url, wp)
req, err := c.NewRequest(ctx, "PUT", url, wp)
if err != nil {
return err
@ -97,11 +98,11 @@ func (c *Client) SetWebProfile(wp WebProfile) error {
// DeleteWebProfile deletes a web experience profile from Paypal with given id
//
// Endpoint: DELETE /v1/payment-experience/web-profiles
func (c *Client) DeleteWebProfile(profileID string) error {
func (c *Client) DeleteWebProfile(ctx context.Context, profileID string) error {
url := fmt.Sprintf("%s%s%s", c.APIBase, "/v1/payment-experience/web-profiles/", profileID)
req, err := c.NewRequest("DELETE", url, nil)
req, err := c.NewRequest(ctx, "DELETE", url, nil)
if err != nil {
return err