mirror of
https://github.com/plutov/paypal.git
synced 2025-01-23 02:11:02 +01:00
GetAuthorization, CreatePayment, tests, README
This commit is contained in:
parent
04214cbc33
commit
0c8d78e8a2
67
README.md
67
README.md
|
@ -6,10 +6,18 @@
|
|||
* POST /v1/oauth2/token
|
||||
* POST /v1/payments/payment
|
||||
* GET /v1/payments/payment/%ID%
|
||||
- GET /v1/payments/payment
|
||||
* GET /v1/payments/payment
|
||||
* GET /v1/payments/authorization/%ID%
|
||||
* POST /v1/payments/authorization/%ID%/capture
|
||||
* POST /v1/payments/authorization/%ID%/void
|
||||
* POST /v1/payments/authorization/%ID%/reauthorize
|
||||
|
||||
#### Create client
|
||||
|
||||
```go
|
||||
import "github.com/logpacker/paypalsdk"
|
||||
```
|
||||
|
||||
```go
|
||||
// Create a client instance
|
||||
c, err := paypalsdk.NewClient("clietnid", "secret", paypalsdk.APIBaseSandBox)
|
||||
|
@ -40,6 +48,39 @@ paymentResult, err := c.CreateDirectPaypalPayment(amount, redirectURI, cancelURI
|
|||
// After approval user will be redirected to return_url from Request with PaymentID
|
||||
```
|
||||
|
||||
### Create any payment
|
||||
```go
|
||||
p := paypalsdk.Payment{
|
||||
Intent: "sale",
|
||||
Payer: &paypalsdk.Payer{
|
||||
PaymentMethod: "credit_card",
|
||||
FundingInstruments: []paypalsdk.FundingInstrument{paypalsdk.FundingInstrument{
|
||||
CreditCard: &paypalsdk.CreditCard{
|
||||
Number: "4111111111111111",
|
||||
Type: "visa",
|
||||
ExpireMonth: "11",
|
||||
ExpireYear: "2020",
|
||||
CVV2: "777",
|
||||
FirstName: "John",
|
||||
LastName: "Doe",
|
||||
},
|
||||
}},
|
||||
},
|
||||
Transactions: []paypalsdk.Transaction{paypalsdk.Transaction{
|
||||
Amount: &paypalsdk.Amount{
|
||||
Currency: "USD",
|
||||
Total: "200",
|
||||
},
|
||||
Description: "My Payment",
|
||||
}},
|
||||
RedirectURLs: &paypalsdk.RedirectURLs{
|
||||
ReturnURL: "http://...",
|
||||
CancelURL: "http://...",
|
||||
},
|
||||
}
|
||||
paymentResponse, err := client.CreatePayment(p)
|
||||
```
|
||||
|
||||
#### Execute approved payment
|
||||
|
||||
```go
|
||||
|
@ -64,3 +105,27 @@ payment, err := c.GetPayment(paymentID)
|
|||
// Get all payments slice
|
||||
payments, err := c.GetPayments()
|
||||
```
|
||||
|
||||
#### Get authorization by ID
|
||||
|
||||
```go
|
||||
auth, err := c.GetAuthorization("AUTH-1")
|
||||
```
|
||||
|
||||
#### Capture authorization
|
||||
|
||||
```go
|
||||
capture, err := c.CaptureAuthorization("AUTH-1", &paypalsdk.Amount{Total: "200", Currency: "USD"}, true)
|
||||
```
|
||||
|
||||
#### Void authorization
|
||||
|
||||
```go
|
||||
auth, err := c.VoidAuthorization("AUTH-1")
|
||||
```
|
||||
|
||||
#### Reauthorize authorization
|
||||
|
||||
```go
|
||||
auth, err := c.ReauthorizeAuthorization("AUTH-1", &paypalsdk.Amount{Total: "200", Currency: "USD"})
|
||||
```
|
||||
|
|
79
auth.go
79
auth.go
|
@ -27,3 +27,82 @@ func (c *Client) GetAccessToken() (*TokenResponse, error) {
|
|||
|
||||
return &t, err
|
||||
}
|
||||
|
||||
// GetAuthorization returns an authorization by ID
|
||||
func (c *Client) GetAuthorization(authID string) (*Authorization, error) {
|
||||
buf := bytes.NewBuffer([]byte(""))
|
||||
req, err := http.NewRequest("GET", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/authorization/"+authID), buf)
|
||||
if err != nil {
|
||||
return &Authorization{}, err
|
||||
}
|
||||
|
||||
auth := &Authorization{}
|
||||
|
||||
err = c.SendWithAuth(req, auth)
|
||||
if err != nil {
|
||||
return auth, err
|
||||
}
|
||||
|
||||
return auth, nil
|
||||
}
|
||||
|
||||
// CaptureAuthorization captures and process an existing authorization.
|
||||
// To use this method, the original payment must have Intent set to "authorize"
|
||||
func (c *Client) CaptureAuthorization(authID string, a *Amount, isFinalCapture bool) (*Capture, error) {
|
||||
isFinalStr := "false"
|
||||
if isFinalCapture {
|
||||
isFinalStr = "true"
|
||||
}
|
||||
buf := bytes.NewBuffer([]byte("{\"amount\":{\"currency\":\"" + a.Currency + "\",\"total\":\"" + a.Total + "\"},\"is_final_capture\":" + isFinalStr + "}"))
|
||||
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/authorization/"+authID+"/capture"), buf)
|
||||
if err != nil {
|
||||
return &Capture{}, err
|
||||
}
|
||||
|
||||
capture := &Capture{}
|
||||
|
||||
err = c.SendWithAuth(req, capture)
|
||||
if err != nil {
|
||||
return capture, err
|
||||
}
|
||||
|
||||
return capture, nil
|
||||
}
|
||||
|
||||
// VoidAuthorization voids a previously authorized payment
|
||||
func (c *Client) VoidAuthorization(authID string) (*Authorization, error) {
|
||||
buf := bytes.NewBuffer([]byte(""))
|
||||
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/authorization/"+authID+"/void"), buf)
|
||||
if err != nil {
|
||||
return &Authorization{}, err
|
||||
}
|
||||
|
||||
auth := &Authorization{}
|
||||
|
||||
err = c.SendWithAuth(req, auth)
|
||||
if err != nil {
|
||||
return auth, err
|
||||
}
|
||||
|
||||
return auth, nil
|
||||
}
|
||||
|
||||
// ReauthorizeAuthorization reauthorize a Paypal account payment.
|
||||
// PayPal recommends to reauthorize payment after ~3 days
|
||||
func (c *Client) ReauthorizeAuthorization(authID string, a *Amount) (*Authorization, error) {
|
||||
buf := bytes.NewBuffer([]byte("{\"amount\":{\"currency\":\"" + a.Currency + "\",\"total\":\"" + a.Total + "\"}}"))
|
||||
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/authorization/"+authID+"/reauthorize"), buf)
|
||||
if err != nil {
|
||||
return &Authorization{}, err
|
||||
}
|
||||
|
||||
auth := &Authorization{}
|
||||
|
||||
err = c.SendWithAuth(req, auth)
|
||||
if err != nil {
|
||||
return auth, err
|
||||
}
|
||||
|
||||
return auth, nil
|
||||
|
||||
}
|
||||
|
|
44
auth_test.go
44
auth_test.go
|
@ -8,3 +8,47 @@ func TestGetAccessToken(t *testing.T) {
|
|||
c, _ := NewClient("clid", "secret", APIBaseSandBox)
|
||||
c.GetAccessToken()
|
||||
}
|
||||
|
||||
func TestGetAuthorization(t *testing.T) {
|
||||
c, _ := NewClient("clid", "secret", APIBaseSandBox)
|
||||
c.GetAccessToken()
|
||||
|
||||
_, err := c.GetAuthorization("123")
|
||||
|
||||
if err == nil {
|
||||
t.Errorf("Error must be returned for invalid Auth ID")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCaptureAuthorization(t *testing.T) {
|
||||
c, _ := NewClient("clid", "secret", APIBaseSandBox)
|
||||
c.GetAccessToken()
|
||||
|
||||
_, err := c.CaptureAuthorization("123", &Amount{Total: "200", Currency: "USD"}, true)
|
||||
|
||||
if err == nil {
|
||||
t.Errorf("Error must be returned for invalid Auth ID")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVoidAuthorization(t *testing.T) {
|
||||
c, _ := NewClient("clid", "secret", APIBaseSandBox)
|
||||
c.GetAccessToken()
|
||||
|
||||
_, err := c.VoidAuthorization("123")
|
||||
|
||||
if err == nil {
|
||||
t.Errorf("Error must be returned for invalid Auth ID")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReauthorizeAuthorization(t *testing.T) {
|
||||
c, _ := NewClient("clid", "secret", APIBaseSandBox)
|
||||
c.GetAccessToken()
|
||||
|
||||
_, err := c.ReauthorizeAuthorization("123", &Amount{Total: "200", Currency: "USD"})
|
||||
|
||||
if err == nil {
|
||||
t.Errorf("Error must be returned for invalid Auth ID")
|
||||
}
|
||||
}
|
||||
|
|
20
client.go
20
client.go
|
@ -1,6 +1,7 @@
|
|||
package paypalsdk
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
|
@ -92,11 +93,28 @@ func (c *Client) Send(req *http.Request, v interface{}) error {
|
|||
// If the access token soon to be expired, it will try to get a new one before
|
||||
// making the main request
|
||||
func (c *Client) SendWithAuth(req *http.Request, v interface{}) error {
|
||||
req.Header.Set("Authorization", "Bearer "+c.Token.Token)
|
||||
if c.Token != nil {
|
||||
req.Header.Set("Authorization", "Bearer "+c.Token.Token)
|
||||
}
|
||||
|
||||
return c.Send(req, v)
|
||||
}
|
||||
|
||||
// NewRequest constructs a request
|
||||
// Convert payload to a JSON
|
||||
func (c *Client) NewRequest(method, url string, payload interface{}) (*http.Request, error) {
|
||||
var buf io.Reader
|
||||
if payload != nil {
|
||||
var b []byte
|
||||
b, err := json.Marshal(&payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf = bytes.NewBuffer(b)
|
||||
}
|
||||
return http.NewRequest(method, url, buf)
|
||||
}
|
||||
|
||||
func (c *Client) log(req *http.Request, resp *http.Response) {
|
||||
if c.LogFile != "" {
|
||||
os.OpenFile(c.LogFile, os.O_CREATE, 0755)
|
||||
|
|
|
@ -35,5 +35,41 @@ func main() {
|
|||
fmt.Println("ERROR: " + err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
p := paypalsdk.Payment{
|
||||
Intent: "sale",
|
||||
Payer: &paypalsdk.Payer{
|
||||
PaymentMethod: "credit_card",
|
||||
FundingInstruments: []paypalsdk.FundingInstrument{paypalsdk.FundingInstrument{
|
||||
CreditCard: &paypalsdk.CreditCard{
|
||||
Number: "4111111111111111",
|
||||
Type: "visa",
|
||||
ExpireMonth: "11",
|
||||
ExpireYear: "2020",
|
||||
CVV2: "777",
|
||||
FirstName: "John",
|
||||
LastName: "Doe",
|
||||
},
|
||||
}},
|
||||
},
|
||||
Transactions: []paypalsdk.Transaction{paypalsdk.Transaction{
|
||||
Amount: &paypalsdk.Amount{
|
||||
Currency: "USD",
|
||||
Total: "200",
|
||||
},
|
||||
Description: "My Payment",
|
||||
}},
|
||||
RedirectURLs: &paypalsdk.RedirectURLs{
|
||||
ReturnURL: "http://...",
|
||||
CancelURL: "http://...",
|
||||
},
|
||||
}
|
||||
paymentResponse, err := client.CreatePayment(p)
|
||||
if err == nil {
|
||||
fmt.Println("DEBUG: CreatedPaymentID=" + paymentResponse.Payment.ID)
|
||||
} else {
|
||||
fmt.Println("ERROR: " + err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("OK")
|
||||
}
|
||||
|
|
24
payment.go
24
payment.go
|
@ -12,7 +12,14 @@ type ListPaymentsResp struct {
|
|||
Payments []Payment `json:"payments"`
|
||||
}
|
||||
|
||||
// CreatePaymentResp returned by CreatePayment
|
||||
type CreatePaymentResp struct {
|
||||
*Payment
|
||||
Links []Links `json:"links"`
|
||||
}
|
||||
|
||||
// CreateDirectPaypalPayment sends request with payment
|
||||
// CreatePayment is more common function for any kind of payment
|
||||
func (c *Client) CreateDirectPaypalPayment(amount Amount, redirectURI string, cancelURI string, description string) (*PaymentResponse, error) {
|
||||
buf := bytes.NewBuffer([]byte("{\"intent\":\"sale\",\"payer\":{\"payment_method\":\"paypal\"}," +
|
||||
"\"transactions\":[{\"amount\":{\"total\":\"" + amount.Total +
|
||||
|
@ -39,6 +46,23 @@ func (c *Client) CreateDirectPaypalPayment(amount Amount, redirectURI string, ca
|
|||
return &p, err
|
||||
}
|
||||
|
||||
// CreatePayment creates a payment in Paypal
|
||||
func (c *Client) CreatePayment(p Payment) (*CreatePaymentResp, error) {
|
||||
req, err := c.NewRequest("POST", fmt.Sprintf("%s%s", c.APIBase, "/v1/payments/payment"), p)
|
||||
if err != nil {
|
||||
return &CreatePaymentResp{}, err
|
||||
}
|
||||
|
||||
response := &CreatePaymentResp{}
|
||||
|
||||
err = c.SendWithAuth(req, response)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// ExecuteApprovedPayment executes approved payment
|
||||
func (c *Client) ExecuteApprovedPayment(paymentID string, payerID string) (*ExecuteResponse, error) {
|
||||
buf := bytes.NewBuffer([]byte("{\"payer_id\":\"" + payerID + "\"}"))
|
||||
|
|
35
types.go
35
types.go
|
@ -25,6 +25,33 @@ type (
|
|||
Token *TokenResponse
|
||||
}
|
||||
|
||||
// Authorization maps to the authorization object
|
||||
Authorization struct {
|
||||
Amount *Amount `json:"amount,omitempty"`
|
||||
CreateTime *time.Time `json:"create_time,omitempty"`
|
||||
UpdateTime *time.Time `json:"update_time,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
ParentPayment string `json:"parent_payment,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
ValidUntil *time.Time `json:"valid_until,omitempty"`
|
||||
Links []Links `json:"links,omitempty"`
|
||||
ClearingTime string `json:"clearing_time,omitempty"`
|
||||
ProtectionEligibility string `json:"protection_eligibility,omitempty"`
|
||||
ProtectionEligibilityType string `json:"protection_eligibility_type,omitempty"`
|
||||
}
|
||||
|
||||
// Capture maps to the capture object
|
||||
Capture struct {
|
||||
Amount *Amount `json:"amount,omitempty"`
|
||||
IsFinalCapture bool `json:"is_final_capture"`
|
||||
CreateTime *time.Time `json:"create_time,omitempty"`
|
||||
UpdateTime *time.Time `json:"update_time,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
ParentPayment string `json:"parent_payment,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Links []Links `json:"links,omitempty"`
|
||||
}
|
||||
|
||||
// Address maps to address object
|
||||
Address struct {
|
||||
Line1 string `json:"line1"`
|
||||
|
@ -135,6 +162,14 @@ type (
|
|||
CancelURL string `json:"cancel_url,omitempty"`
|
||||
}
|
||||
|
||||
// Links maps to links object
|
||||
Links struct {
|
||||
Href string `json:"href"`
|
||||
Rel string `json:"rel"`
|
||||
Method string `json:"method"`
|
||||
Enctype string `json:"enctype"`
|
||||
}
|
||||
|
||||
// Payment maps to payment object
|
||||
Payment struct {
|
||||
Intent string `json:"intent"`
|
||||
|
|
Loading…
Reference in New Issue
Block a user