Compare commits

..

1 Commits

Author SHA1 Message Date
Alex Pliutau
db239bf6a5
Update README.md 2024-07-11 10:23:55 +02:00
9 changed files with 92 additions and 60 deletions

View File

@ -1,16 +1,6 @@
name: Lint and Test name: Lint and Test
on: on: push
push:
branches:
- features/*
- testing/*
- fix/*
- enhance/*
pull_request:
branches:
- master
- staging
jobs: jobs:
lint: lint:
@ -21,7 +11,7 @@ jobs:
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: "1.23" go-version: "1.21.x"
- name: Install dependencies - name: Install dependencies
run: go get . run: go get .
- name: Install linters - name: Install linters
@ -43,7 +33,7 @@ jobs:
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: "1.23" go-version: "1.21.x"
- name: Install dependencies - name: Install dependencies
run: go get . run: go get .
- name: Run Tests - name: Run Tests

1
.gitignore vendored
View File

@ -1,3 +1,2 @@
.idea .idea
.vscode .vscode
vendor/

View File

@ -1,10 +0,0 @@
First off all, thank you for considering contributing to this project. It's people like you that make it such a great tool.
Keep an open mind! Improving documentation, bug triaging, or writing tutorials are all examples of helpful contributions that mean less work for you.
Some basic suggestions to get you started:
- Make sure the PR is up-to-date with the latest changes in the main branch.
- Make sure the PR passes all the tests.
- Make sure the PR passes the linter.
- Make sure the PR is well documented and formatted.
- Make sure the PR is well tested.

View File

@ -1,10 +1,5 @@
[Docs](https://pkg.go.dev/github.com/plutov/paypal) [Docs](https://pkg.go.dev/github.com/plutov/paypal)
<p>
<a href="https://github.com/plutov/paypal/releases"><img src="https://img.shields.io/github/release/plutov/paypal.svg" alt="Latest Release"></a>
<a href="https://pkg.go.dev/github.com/plutov/paypal?tab=doc"><img src="https://godoc.org/github.com/golang/gddo?status.svg" alt="GoDoc"></a>
</p>
# Go client for PayPal REST API # Go client for PayPal REST API
## Paypal REST API Docs ## Paypal REST API Docs
@ -67,7 +62,7 @@ order, err := c.GetOrder("O-4J082351X3132253H")
ctx := context.Background() ctx := context.Background()
units := []paypal.PurchaseUnitRequest{} units := []paypal.PurchaseUnitRequest{}
source := &paypal.PaymentSource{} source := &paypal.PaymentSource{}
appCtx := &paypal.ApplicationContext{} appCtx := &paypalApplicationContext{}
order, err := c.CreateOrder(ctx, paypal.OrderIntentCapture, units, ource, appCtx) order, err := c.CreateOrder(ctx, paypal.OrderIntentCapture, units, ource, appCtx)
``` ```
@ -299,10 +294,10 @@ invoice, err := c.GetInvoiceDetails(ctx, "INV2-XFXV-YW42-ZANU-4F33")
- Check that tests are passing - Check that tests are passing
- Create PR - Create PR
Main contributors: Current contributors:
- [Alex Pliutau](https://github.com/plutov)
- [Roopak Venkatakrishnan](https://github.com/roopakv) - [Roopak Venkatakrishnan](https://github.com/roopakv)
- [Alex Pliutau](https://packagemain.tech)
## Tests ## Tests

View File

@ -97,23 +97,13 @@ func (c *Client) Send(req *http.Request, v interface{}) error {
if c.returnRepresentation { if c.returnRepresentation {
req.Header.Set("Prefer", "return=representation") req.Header.Set("Prefer", "return=representation")
} }
if c.Log != nil {
if reqDump, err := httputil.DumpRequestOut(req, true); err == nil {
c.Log.Write([]byte(fmt.Sprintf("Request: %s\n", reqDump)))
}
}
resp, err = c.Client.Do(req) resp, err = c.Client.Do(req)
c.log(req, resp)
if err != nil { if err != nil {
return err return err
} }
if c.Log != nil {
if respDump, err := httputil.DumpResponse(resp, true); err == nil {
c.Log.Write([]byte(fmt.Sprintf("Response from %s: %s\n", req.URL, respDump)))
}
}
defer func(Body io.ReadCloser) error { defer func(Body io.ReadCloser) error {
return Body.Close() return Body.Close()
}(resp.Body) }(resp.Body)
@ -190,3 +180,22 @@ func (c *Client) NewRequest(ctx context.Context, method, url string, payload int
} }
return http.NewRequestWithContext(ctx, method, url, buf) return http.NewRequestWithContext(ctx, method, url, buf)
} }
// log will dump request and response to the log file
func (c *Client) log(r *http.Request, resp *http.Response) {
if c.Log != nil {
var (
reqDump string
respDump []byte
)
if r != nil {
reqDump = fmt.Sprintf("%s %s. Data: %s", r.Method, r.URL.String(), r.Form.Encode())
}
if resp != nil {
respDump, _ = httputil.DumpResponse(resp, true)
}
c.Log.Write([]byte(fmt.Sprintf("Request: %s\nResponse: %s\n", reqDump, string(respDump))))
}
}

4
go.mod
View File

@ -1,6 +1,6 @@
module euphoria-laxis.fr/go-packages/paypale/v4 module github.com/plutov/paypal/v4
go 1.23 go 1.21
require github.com/stretchr/testify v1.9.0 require github.com/stretchr/testify v1.9.0

View File

@ -4,10 +4,59 @@ import (
"context" "context"
"fmt" "fmt"
"net/http" "net/http"
"net/url"
"strings"
) )
// 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(ctx context.Context, code, redirectURI string) (*TokenResponse, error) {
token := &TokenResponse{}
q := url.Values{}
q.Set("grant_type", "authorization_code")
q.Set("code", code)
q.Set("redirect_uri", redirectURI)
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
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
if err = c.SendWithBasicAuth(req, token); err != nil {
return token, err
}
return token, nil
}
// GrantNewAccessTokenFromRefreshToken - Use this call to grant a new access token, using a refresh token.
// Endpoint: POST /v1/identity/openidconnect/tokenservice
func (c *Client) GrantNewAccessTokenFromRefreshToken(ctx context.Context, refreshToken string) (*TokenResponse, error) {
type request struct {
GrantType string `json:"grant_type"`
RefreshToken string `json:"refresh_token"`
}
token := &TokenResponse{}
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
}
if err = c.SendWithAuth(req, token); err != nil {
return token, err
}
return token, nil
}
// GetUserInfo - Use this call to retrieve user profile attributes. // GetUserInfo - Use this call to retrieve user profile attributes.
// Endpoint: GET /v1/identity/openidconnect/userinfo/?schema=<Schema> // 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(ctx context.Context, schema string) (*UserInfo, error) { func (c *Client) GetUserInfo(ctx context.Context, schema string) (*UserInfo, error) {
u := &UserInfo{} u := &UserInfo{}

View File

@ -5,7 +5,7 @@ import (
"encoding/json" "encoding/json"
"testing" "testing"
"euphoria-laxis.fr/go-packages/paypale/v4" "github.com/plutov/paypal/v4"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )

View File

@ -12,10 +12,10 @@ import (
const ( const (
// APIBaseSandBox points to the sandbox (for testing) version of the API // APIBaseSandBox points to the sandbox (for testing) version of the API
APIBaseSandBox = "https://api-m.sandbox.paypal.com" APIBaseSandBox = "https://api.sandbox.paypal.com"
// APIBaseLive points to the live version of the API // APIBaseLive points to the live version of the API
APIBaseLive = "https://api-m.paypal.com" APIBaseLive = "https://api.paypal.com"
// RequestNewTokenBeforeExpiresIn is used by SendWithAuth and try to get new Token when it's about to expire // RequestNewTokenBeforeExpiresIn is used by SendWithAuth and try to get new Token when it's about to expire
RequestNewTokenBeforeExpiresIn = time.Duration(60) * time.Second RequestNewTokenBeforeExpiresIn = time.Duration(60) * time.Second
@ -1057,14 +1057,14 @@ type (
// PaymentSourceCard structure // PaymentSourceCard structure
PaymentSourceCard struct { PaymentSourceCard struct {
ID string `json:"id,omitempty"` ID string `json:"id"`
Name string `json:"name,omitempty"` Name string `json:"name"`
Number string `json:"number,omitempty"` Number string `json:"number"`
Expiry string `json:"expiry,omitempty"` Expiry string `json:"expiry"`
SecurityCode string `json:"security_code,omitempty"` SecurityCode string `json:"security_code"`
LastDigits string `json:"last_digits,omitempty"` LastDigits string `json:"last_digits"`
CardType string `json:"card_type,omitempty"` CardType string `json:"card_type"`
BillingAddress *CardBillingAddress `json:"billing_address,omitempty"` BillingAddress *CardBillingAddress `json:"billing_address"`
} }
// PaymentSourcePaypal structure // PaymentSourcePaypal structure
@ -1086,8 +1086,8 @@ type (
// CardBillingAddress structure // CardBillingAddress structure
CardBillingAddress struct { CardBillingAddress struct {
AddressLine1 string `json:"address_line_1"` AddressLine1 string `json:"address_line_1"`
AddressLine2 string `json:"address_line_2,omitempty"` AddressLine2 string `json:"address_line_2"`
AdminArea2 string `json:"admin_area_2,omitempty"` AdminArea2 string `json:"admin_area_2"`
AdminArea1 string `json:"admin_area_1"` AdminArea1 string `json:"admin_area_1"`
PostalCode string `json:"postal_code"` PostalCode string `json:"postal_code"`
CountryCode string `json:"country_code"` CountryCode string `json:"country_code"`