paypal

package module
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 22, 2023 License: MIT Imports: 9 Imported by: 2

README

A PayPal API library written in Go

This library sets up a PayPal transaction and captures the transaction funds.

ShippingPreference defaults to NO_SHIPPING, so the PayPal window won't show the shipping information. Our example code does not send any shipping information to PayPal.

Example of usage

For the client side, follow:

On the server, first create a paypal.Config or load it from a JSON file:

paypalConfig, err := paypal.Load("paypal.json")
if err != nil {
	return err
}

Then set up a transaction:

// authenticate
authResult, err := paypalConfig.Auth()
if err != nil {
	return err
}

// call PayPal API to generate an order
generateOrderResponse, err := paypalConfig.CreateOrder(authResult, amountInCents)
if err != nil {
	return err
}

// return ID of generated order to the client
successResponse, err := json.Marshal(&paypal.SuccessResponse{OrderID: generateOrderResponse.ID})
if err != nil {
	return err
}
w.Header().Set("Content-Type", "application/json")
w.Write(successResponse)

Capture the funds:

// get the PayPal OrderID from the client, e.g. from the request body
captureRequest := &paypal.CaptureRequest{}
if err := json.NewDecoder(r.Body).Decode(captureRequest); err != nil {
	return err
}

// authenticate
authResult, err := paypalConfig.Auth()
if err != nil {
	return err
}

// call PayPal to capture the funds
captureResponse, err := paypalConfig.Capture(authResult, captureRequest.OrderID)
if err != nil {
	return err
}

// save the capture ID to your database
// captureResponse.PurchaseUnits[0].Payments.Captures[0].ID

// looks like the handler must return some JSON to the client, although the PayPal docs don't mention that
w.Header().Set("Content-Type", "application/json")
w.Write([]byte("true"))

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Create

func Create(jsonPath string) error

Create creates an empty json config file with empty values and chmod 600, so someone can fill in easily. Create always returns an error.

Types

type Amount

type Amount struct {
	CurrencyCode string  `json:"currency_code"`
	Value        float64 `json:"value"`
}

type ApplicationContext

type ApplicationContext struct {
	ShippingPreference string `json:"shipping_preference"`
}

type AuthResult

type AuthResult struct {
	Scope       string `json:"scope"`
	AccessToken string `json:"access_token"`
	TokenType   string `json:"token_type"`
	AppID       string `json:"app_id"`
	ExpiresIn   int    `json:"expires_in"`
	Nonce       string `json:"nonce"`
}

type CaptureRequest

type CaptureRequest struct {
	OrderID string `json:"orderID"`
}

type CaptureResponse

type CaptureResponse struct {
	ID            string `json:"id"`
	Status        string `json:"status"`
	PaymentSource struct {
		Paypal struct {
			EmailAddress  string `json:"email_address"`
			AccountID     string `json:"account_id"`
			AccountStatus string `json:"account_status"`
			Name          struct {
				GivenName string `json:"given_name"`
				Surname   string `json:"surname"`
			} `json:"name"`
			Address struct {
				CountryCode string `json:"country_code"`
			} `json:"address"`
		} `json:"paypal"`
	} `json:"payment_source"`
	PurchaseUnits []struct {
		ReferenceID string `json:"reference_id"`
		Shipping    struct {
			Address struct {
				AddressLine1 string `json:"address_line_1"`
				AddressLine2 string `json:"address_line_2"`
				AdminArea2   string `json:"admin_area_2"`
				AdminArea1   string `json:"admin_area_1"`
				PostalCode   string `json:"postal_code"`
				CountryCode  string `json:"country_code"`
			} `json:"address"`
		} `json:"shipping"`
		Payments struct {
			Captures []struct {
				ID     string `json:"id"`
				Status string `json:"status"`
				Amount struct {
					CurrencyCode string `json:"currency_code"`
					Value        string `json:"value"`
				} `json:"amount"`
				FinalCapture     bool `json:"final_capture"`
				SellerProtection struct {
					Status            string   `json:"status"`
					DisputeCategories []string `json:"dispute_categories"`
				} `json:"seller_protection"`
				SellerReceivableBreakdown struct {
					GrossAmount struct {
						CurrencyCode string `json:"currency_code"`
						Value        string `json:"value"`
					} `json:"gross_amount"`
					PaypalFee struct {
						CurrencyCode string `json:"currency_code"`
						Value        string `json:"value"`
					} `json:"paypal_fee"`
					NetAmount struct {
						CurrencyCode string `json:"currency_code"`
						Value        string `json:"value"`
					} `json:"net_amount"`
				} `json:"seller_receivable_breakdown"`
				InvoiceID string `json:"invoice_id"`
				Links     []struct {
					Href   string `json:"href"`
					Rel    string `json:"rel"`
					Method string `json:"method"`
				} `json:"links"`
				CreateTime time.Time `json:"create_time"`
				UpdateTime time.Time `json:"update_time"`
			} `json:"captures"`
		} `json:"payments"`
	} `json:"purchase_units"`
	Payer struct {
		Name struct {
			GivenName string `json:"given_name"`
			Surname   string `json:"surname"`
		} `json:"name"`
		EmailAddress string `json:"email_address"`
		PayerID      string `json:"payer_id"`
		Address      struct {
			CountryCode string `json:"country_code"`
		} `json:"address"`
	} `json:"payer"`
	Links []struct {
		Href   string `json:"href"`
		Rel    string `json:"rel"`
		Method string `json:"method"`
	} `json:"links"`
}

Generated 2023-11-22 with json-to-go from docs (Shipping) and a real response (the rest). Note that PurchaseUnits does not contain the custom_id.

type Config

type Config struct {
	OAuthAPI string `json:"oauth-api"`
	OrderAPI string `json:"order-api"`
	ClientID string `json:"client-id"`
	Secret   string `json:"secret"`
}

func Load

func Load(jsonPath string) (*Config, error)

Load unmarshals a json config file into a Config. If the file doesn't exist, it is created and an error is returned.

func (*Config) Auth

func (config *Config) Auth() (*AuthResult, error)

Auth gets an access token from the PayPal API.

func (*Config) Capture

func (config *Config) Capture(auth *AuthResult, orderID string) (*CaptureResponse, error)

Capture calls PayPal to capture the order.

func (*Config) CreateOrder

func (config *Config) CreateOrder(auth *AuthResult, description, invoiceID, referenceID string, euroCents int) (*GenerateOrderResponse, error)

CreateOrder calls PayPal to set up a transaction.

type GenerateOrderResponse

type GenerateOrderResponse struct {
	ID     string `json:"id"`     // like "1AB23456CD789012E"
	Status string `json:"status"` // like "CREATED"
	Links  []struct {
		Href   string `json:"href"`
		Rel    string `json:"rel"`
		Method string `json:"method"`
	} `json:"links"`
}

type OrderRequest

type OrderRequest struct {
	Intent             string             `json:"intent"`
	PurchaseUnits      []PurchaseUnit     `json:"purchase_units"`
	ApplicationContext ApplicationContext `json:"application_context"`
}

type PurchaseUnit

type PurchaseUnit struct {
	ReferenceID string `json:"reference_id,omitempty"` // "[ 1 .. 256 ] characters: The API caller-provided external ID for the purchase unit.", omitempty because paypal fails if it exists but is empty
	Description string `json:"description"`            // "[ 1 .. 127 ] characters: The purchase description."
	InvoiceID   string `json:"invoice_id"`             // "[ 1 .. 127 ] characters: The API caller-provided external invoice ID for this order. Appears in both the payer's transaction history and the emails that the payer receives."
	Amount      Amount `json:"amount"`
}

See https://developer.paypal.com/docs/api/orders/v2/#definition-purchase_unit

type SuccessResponse

type SuccessResponse struct {
	OrderID string `json:"id"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL