Skip to content

Commit cc8b3ce

Browse files
committed
add context support
1 parent 0f9d1cc commit cc8b3ce

21 files changed

+235
-210
lines changed

.travis.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
language: go
22
go:
3-
- 1.11
4-
- 1.12
3+
- 1.13
4+
- 1.14
5+
- 1.15
56
install:
67
- export PATH=$PATH:$HOME/gopath/bin
78
script:

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,14 @@ It is possible that some endpoints are missing in this SDK Client, but you can u
8282

8383
```go
8484
// If using Go Modules
85-
// import "github.com/plutov/paypal/v3"
85+
// import "github.com/plutov/paypal/v4"
8686
import "github.com/plutov/paypal"
8787

8888
// Create a client instance
8989
c, err := paypal.NewClient("clientID", "secretID", paypal.APIBaseSandBox)
9090
c.SetLog(os.Stdout) // Set log to terminal stdout
9191

92-
accessToken, err := c.GetAccessToken()
92+
accessToken, err := c.GetAccessToken(context.Background())
9393
```
9494

9595
### How to Contribute

authorization.go

+11-10
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ package paypal
22

33
import (
44
"bytes"
5+
"context"
56
"fmt"
67
"net/http"
78
)
89

910
// GetAuthorization returns an authorization by ID
1011
// Endpoint: GET /v2/payments/authorizations/ID
11-
func (c *Client) GetAuthorization(authID string) (*Authorization, error) {
12+
func (c *Client) GetAuthorization(ctx context.Context, authID string) (*Authorization, error) {
1213
buf := bytes.NewBuffer([]byte(""))
13-
req, err := http.NewRequest("GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v2/payments/authorizations/", authID), buf)
14+
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v2/payments/authorizations/", authID), buf)
1415
auth := &Authorization{}
1516

1617
if err != nil {
@@ -24,19 +25,19 @@ func (c *Client) GetAuthorization(authID string) (*Authorization, error) {
2425
// CaptureAuthorization captures and process an existing authorization.
2526
// To use this method, the original payment must have Intent set to "authorize"
2627
// Endpoint: POST /v2/payments/authorizations/ID/capture
27-
func (c *Client) CaptureAuthorization(authID string, paymentCaptureRequest *PaymentCaptureRequest) (*PaymentCaptureResponse, error) {
28-
return c.CaptureAuthorizationWithPaypalRequestId(authID, paymentCaptureRequest, "")
28+
func (c *Client) CaptureAuthorization(ctx context.Context, authID string, paymentCaptureRequest *PaymentCaptureRequest) (*PaymentCaptureResponse, error) {
29+
return c.CaptureAuthorizationWithPaypalRequestId(ctx, authID, paymentCaptureRequest, "")
2930
}
3031

3132
// CaptureAuthorization captures and process an existing authorization with idempotency.
3233
// To use this method, the original payment must have Intent set to "authorize"
3334
// Endpoint: POST /v2/payments/authorizations/ID/capture
34-
func (c *Client) CaptureAuthorizationWithPaypalRequestId(
35+
func (c *Client) CaptureAuthorizationWithPaypalRequestId(ctx context.Context,
3536
authID string,
3637
paymentCaptureRequest *PaymentCaptureRequest,
3738
requestID string,
3839
) (*PaymentCaptureResponse, error) {
39-
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/authorizations/"+authID+"/capture"), paymentCaptureRequest)
40+
req, err := c.NewRequest(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/authorizations/"+authID+"/capture"), paymentCaptureRequest)
4041
paymentCaptureResponse := &PaymentCaptureResponse{}
4142

4243
if err != nil {
@@ -53,9 +54,9 @@ func (c *Client) CaptureAuthorizationWithPaypalRequestId(
5354

5455
// VoidAuthorization voids a previously authorized payment
5556
// Endpoint: POST /v2/payments/authorizations/ID/void
56-
func (c *Client) VoidAuthorization(authID string) (*Authorization, error) {
57+
func (c *Client) VoidAuthorization(ctx context.Context, authID string) (*Authorization, error) {
5758
buf := bytes.NewBuffer([]byte(""))
58-
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/authorizations/"+authID+"/void"), buf)
59+
req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/authorizations/"+authID+"/void"), buf)
5960
auth := &Authorization{}
6061

6162
if err != nil {
@@ -69,9 +70,9 @@ func (c *Client) VoidAuthorization(authID string) (*Authorization, error) {
6970
// ReauthorizeAuthorization reauthorize a Paypal account payment.
7071
// PayPal recommends to reauthorize payment after ~3 days
7172
// Endpoint: POST /v2/payments/authorizations/ID/reauthorize
72-
func (c *Client) ReauthorizeAuthorization(authID string, a *Amount) (*Authorization, error) {
73+
func (c *Client) ReauthorizeAuthorization(ctx context.Context, authID string, a *Amount) (*Authorization, error) {
7374
buf := bytes.NewBuffer([]byte(`{"amount":{"currency":"` + a.Currency + `","total":"` + a.Total + `"}}`))
74-
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/authorizations/"+authID+"/reauthorize"), buf)
75+
req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v2/payments/authorizations/"+authID+"/reauthorize"), buf)
7576
auth := &Authorization{}
7677

7778
if err != nil {

billing.go

+14-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package paypal
22

33
import (
4+
"context"
45
"errors"
56
"fmt"
67
"net/http"
@@ -43,8 +44,8 @@ type (
4344

4445
// CreateBillingPlan creates a billing plan in Paypal
4546
// Endpoint: POST /v1/payments/billing-plans
46-
func (c *Client) CreateBillingPlan(plan BillingPlan) (*CreateBillingResp, error) {
47-
req, err := c.NewRequest(http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-plans"), plan)
47+
func (c *Client) CreateBillingPlan(ctx context.Context, plan BillingPlan) (*CreateBillingResp, error) {
48+
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-plans"), plan)
4849
response := &CreateBillingResp{}
4950
if err != nil {
5051
return response, err
@@ -55,7 +56,7 @@ func (c *Client) CreateBillingPlan(plan BillingPlan) (*CreateBillingResp, error)
5556

5657
// UpdateBillingPlan updates values inside a billing plan
5758
// Endpoint: PATCH /v1/payments/billing-plans
58-
func (c *Client) UpdateBillingPlan(planId string, pathValues map[string]map[string]interface{}) error {
59+
func (c *Client) UpdateBillingPlan(ctx context.Context, planId string, pathValues map[string]map[string]interface{}) error {
5960
patchData := []Patch{}
6061
for path, data := range pathValues {
6162
patchData = append(patchData, Patch{
@@ -64,8 +65,8 @@ func (c *Client) UpdateBillingPlan(planId string, pathValues map[string]map[stri
6465
Value: data,
6566
})
6667
}
67-
68-
req, err := c.NewRequest(http.MethodPatch, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/payments/billing-plans/", planId), patchData)
68+
69+
req, err := c.NewRequest(ctx, http.MethodPatch, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/payments/billing-plans/", planId), patchData)
6970
if err != nil {
7071
return err
7172
}
@@ -76,21 +77,21 @@ func (c *Client) UpdateBillingPlan(planId string, pathValues map[string]map[stri
7677
// ActivatePlan activates a billing plan
7778
// By default, a new plan is not activated
7879
// Endpoint: PATCH /v1/payments/billing-plans/
79-
func (c *Client) ActivatePlan(planID string) error {
80-
return c.UpdateBillingPlan(planID, map[string]map[string]interface{}{
80+
func (c *Client) ActivatePlan(ctx context.Context, planID string) error {
81+
return c.UpdateBillingPlan(ctx, planID, map[string]map[string]interface{}{
8182
"/": {"state": BillingPlanStatusActive},
8283
})
8384
}
8485

8586
// CreateBillingAgreement creates an agreement for specified plan
8687
// Endpoint: POST /v1/payments/billing-agreements
87-
func (c *Client) CreateBillingAgreement(a BillingAgreement) (*CreateAgreementResp, error) {
88+
func (c *Client) CreateBillingAgreement(ctx context.Context, a BillingAgreement) (*CreateAgreementResp, error) {
8889
// PayPal needs only ID, so we will remove all fields except Plan ID
8990
a.Plan = BillingPlan{
9091
ID: a.Plan.ID,
9192
}
9293

93-
req, err := c.NewRequest(http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-agreements"), a)
94+
req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-agreements"), a)
9495
response := &CreateAgreementResp{}
9596
if err != nil {
9697
return response, err
@@ -101,8 +102,8 @@ func (c *Client) CreateBillingAgreement(a BillingAgreement) (*CreateAgreementRes
101102

102103
// ExecuteApprovedAgreement - Use this call to execute (complete) a PayPal agreement that has been approved by the payer.
103104
// Endpoint: POST /v1/payments/billing-agreements/token/agreement-execute
104-
func (c *Client) ExecuteApprovedAgreement(token string) (*ExecuteAgreementResponse, error) {
105-
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/v1/payments/billing-agreements/%s/agreement-execute", c.APIBase, token), nil)
105+
func (c *Client) ExecuteApprovedAgreement(ctx context.Context, token string) (*ExecuteAgreementResponse, error) {
106+
req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/v1/payments/billing-agreements/%s/agreement-execute", c.APIBase, token), nil)
106107
response := &ExecuteAgreementResponse{}
107108

108109
if err != nil {
@@ -125,8 +126,8 @@ func (c *Client) ExecuteApprovedAgreement(token string) (*ExecuteAgreementRespon
125126

126127
// ListBillingPlans lists billing-plans
127128
// Endpoint: GET /v1/payments/billing-plans
128-
func (c *Client) ListBillingPlans(bplp BillingPlanListParams) (*BillingPlanListResp, error) {
129-
req, err := c.NewRequest("GET", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-plans"), nil)
129+
func (c *Client) ListBillingPlans(ctx context.Context, bplp BillingPlanListParams) (*BillingPlanListResp, error) {
130+
req, err := c.NewRequest(ctx, "GET", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/billing-plans"), nil)
130131
response := &BillingPlanListResp{}
131132
if err != nil {
132133
return response, err

client.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package paypal
22

33
import (
44
"bytes"
5+
"context"
56
"encoding/json"
67
"errors"
78
"fmt"
@@ -30,9 +31,9 @@ func NewClient(clientID string, secret string, APIBase string) (*Client, error)
3031
// GetAccessToken returns struct of TokenResponse
3132
// No need to call SetAccessToken to apply new access token for current Client
3233
// Endpoint: POST /v1/oauth2/token
33-
func (c *Client) GetAccessToken() (*TokenResponse, error) {
34+
func (c *Client) GetAccessToken(ctx context.Context) (*TokenResponse, error) {
3435
buf := bytes.NewBuffer([]byte("grant_type=client_credentials"))
35-
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/oauth2/token"), buf)
36+
req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/oauth2/token"), buf)
3637
if err != nil {
3738
return &TokenResponse{}, err
3839
}
@@ -140,7 +141,7 @@ func (c *Client) SendWithAuth(req *http.Request, v interface{}) error {
140141
if c.Token != nil {
141142
if !c.tokenExpiresAt.IsZero() && c.tokenExpiresAt.Sub(time.Now()) < RequestNewTokenBeforeExpiresIn {
142143
// c.Token will be updated in GetAccessToken call
143-
if _, err := c.GetAccessToken(); err != nil {
144+
if _, err := c.GetAccessToken(req.Context()); err != nil {
144145
c.Unlock()
145146
return err
146147
}
@@ -164,7 +165,7 @@ func (c *Client) SendWithBasicAuth(req *http.Request, v interface{}) error {
164165

165166
// NewRequest constructs a request
166167
// Convert payload to a JSON
167-
func (c *Client) NewRequest(method, url string, payload interface{}) (*http.Request, error) {
168+
func (c *Client) NewRequest(ctx context.Context, method, url string, payload interface{}) (*http.Request, error) {
168169
var buf io.Reader
169170
if payload != nil {
170171
b, err := json.Marshal(&payload)
@@ -173,7 +174,7 @@ func (c *Client) NewRequest(method, url string, payload interface{}) (*http.Requ
173174
}
174175
buf = bytes.NewBuffer(b)
175176
}
176-
return http.NewRequest(method, url, buf)
177+
return http.NewRequestWithContext(ctx, method, url, buf)
177178
}
178179

179180
// log will dump request and response to the log file

example_test.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package paypal_test
22

3-
import "github.com/plutov/paypal/v3"
3+
import (
4+
"context"
5+
6+
"github.com/plutov/paypal/v4"
7+
)
48

59
func Example() {
610
// Initialize client
@@ -10,7 +14,7 @@ func Example() {
1014
}
1115

1216
// Retrieve access token
13-
_, err = c.GetAccessToken()
17+
_, err = c.GetAccessToken(context.Background())
1418
if err != nil {
1519
panic(err)
1620
}
@@ -24,7 +28,7 @@ func ExampleClient_CreateSinglePayout_Venmo() {
2428
}
2529

2630
// Retrieve access token
27-
_, err = c.GetAccessToken()
31+
_, err = c.GetAccessToken(context.Background())
2832
if err != nil {
2933
panic(err)
3034
}
@@ -51,5 +55,5 @@ func ExampleClient_CreateSinglePayout_Venmo() {
5155
},
5256
}
5357

54-
c.CreateSinglePayout(payout)
58+
c.CreateSinglePayout(context.Background(), payout)
5559
}

go.mod

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
module github.com/plutov/paypal/v3
1+
module github.com/plutov/paypal/v4
22

3-
go 1.12
3+
go 1.13
44

55
require github.com/stretchr/testify v1.6.0

identity.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package paypal
22

33
import (
4+
"context"
45
"fmt"
56
"net/http"
67
"net/url"
@@ -9,15 +10,15 @@ import (
910

1011
// GrantNewAccessTokenFromAuthCode - Use this call to grant a new access token, using the previously obtained authorization code.
1112
// Endpoint: POST /v1/identity/openidconnect/tokenservice
12-
func (c *Client) GrantNewAccessTokenFromAuthCode(code, redirectURI string) (*TokenResponse, error) {
13+
func (c *Client) GrantNewAccessTokenFromAuthCode(ctx context.Context, code, redirectURI string) (*TokenResponse, error) {
1314
token := &TokenResponse{}
1415

1516
q := url.Values{}
1617
q.Set("grant_type", "authorization_code")
1718
q.Set("code", code)
1819
q.Set("redirect_uri", redirectURI)
1920

20-
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/identity/openidconnect/tokenservice"), strings.NewReader(q.Encode()))
21+
req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/identity/openidconnect/tokenservice"), strings.NewReader(q.Encode()))
2122
if err != nil {
2223
return token, err
2324
}
@@ -33,15 +34,15 @@ func (c *Client) GrantNewAccessTokenFromAuthCode(code, redirectURI string) (*Tok
3334

3435
// GrantNewAccessTokenFromRefreshToken - Use this call to grant a new access token, using a refresh token.
3536
// Endpoint: POST /v1/identity/openidconnect/tokenservice
36-
func (c *Client) GrantNewAccessTokenFromRefreshToken(refreshToken string) (*TokenResponse, error) {
37+
func (c *Client) GrantNewAccessTokenFromRefreshToken(ctx context.Context, refreshToken string) (*TokenResponse, error) {
3738
type request struct {
3839
GrantType string `json:"grant_type"`
3940
RefreshToken string `json:"refresh_token"`
4041
}
4142

4243
token := &TokenResponse{}
4344

44-
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/identity/openidconnect/tokenservice"), request{GrantType: "refresh_token", RefreshToken: refreshToken})
45+
req, err := c.NewRequest(ctx, "POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/identity/openidconnect/tokenservice"), request{GrantType: "refresh_token", RefreshToken: refreshToken})
4546
if err != nil {
4647
return token, err
4748
}
@@ -56,10 +57,10 @@ func (c *Client) GrantNewAccessTokenFromRefreshToken(refreshToken string) (*Toke
5657
// GetUserInfo - Use this call to retrieve user profile attributes.
5758
// Endpoint: GET /v1/identity/openidconnect/userinfo/?schema=<Schema>
5859
// Pass the schema that is used to return as per openidconnect protocol. The only supported schema value is openid.
59-
func (c *Client) GetUserInfo(schema string) (*UserInfo, error) {
60+
func (c *Client) GetUserInfo(ctx context.Context, schema string) (*UserInfo, error) {
6061
u := &UserInfo{}
6162

62-
req, err := http.NewRequest("GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v1/identity/openidconnect/userinfo/?schema=", schema), nil)
63+
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("%s%s%s", c.APIBase, "/v1/identity/openidconnect/userinfo/?schema=", schema), nil)
6364
if err != nil {
6465
return u, err
6566
}

0 commit comments

Comments
 (0)