forked from go-packages/paypal
235 lines
9.4 KiB
Go
235 lines
9.4 KiB
Go
package paypal
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
type (
|
|
SubscriptionBase struct {
|
|
PlanID string `json:"plan_id"`
|
|
StartTime *JSONTime `json:"start_time,omitempty"`
|
|
Quantity string `json:"quantity,omitempty"`
|
|
ShippingAmount *Money `json:"shipping_amount,omitempty"`
|
|
Subscriber *Subscriber `json:"subscriber,omitempty"`
|
|
AutoRenewal bool `json:"auto_renewal,omitempty"`
|
|
ApplicationContext *ApplicationContext `json:"application_context,omitempty"`
|
|
CustomID string `json:"custom_id,omitempty"`
|
|
Plan *PlanOverride `json:"plan,omitempty"`
|
|
}
|
|
|
|
SubscriptionDetails struct {
|
|
ID string `json:"id,omitempty"`
|
|
SubscriptionStatus SubscriptionStatus `json:"status,omitempty"`
|
|
SubscriptionStatusChangeNote string `json:"status_change_note,omitempty"`
|
|
StatusUpdateTime time.Time `json:"status_update_time,omitempty"`
|
|
}
|
|
|
|
Subscription struct {
|
|
SubscriptionDetailResp
|
|
}
|
|
|
|
// SubscriptionDetailResp struct
|
|
SubscriptionDetailResp struct {
|
|
SubscriptionBase
|
|
SubscriptionDetails
|
|
BillingInfo BillingInfo `json:"billing_info,omitempty"` // not found in documentation
|
|
SharedResponse
|
|
}
|
|
|
|
SubscriptionCaptureResponse struct {
|
|
Status SubscriptionTransactionStatus `json:"status"`
|
|
Id string `json:"id"`
|
|
AmountWithBreakdown AmountWithBreakdown `json:"amount_with_breakdown"`
|
|
PayerName Name `json:"payer_name"`
|
|
PayerEmail string `json:"payer_email"`
|
|
Time time.Time `json:"time"`
|
|
}
|
|
|
|
//Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#definition-amount_with_breakdown
|
|
AmountWithBreakdown struct {
|
|
GrossAmount Money `json:"gross_amount"`
|
|
FeeAmount Money `json:"fee_amount"`
|
|
ShippingAmount Money `json:"shipping_amount"`
|
|
TaxAmount Money `json:"tax_amount"`
|
|
NetAmount Money `json:"net_amount"`
|
|
}
|
|
|
|
SubscriptionTransactionsParams struct {
|
|
SubscriptionId string
|
|
StartTime time.Time
|
|
EndTime time.Time
|
|
}
|
|
|
|
SubscriptionTransactionsResponse struct {
|
|
Transactions []SubscriptionCaptureResponse `json:"transactions"`
|
|
SharedListResponse
|
|
}
|
|
|
|
CaptureRequest struct {
|
|
Note string `json:"note"`
|
|
CaptureType CaptureType `json:"capture_type"`
|
|
Amount Money `json:"amount"`
|
|
}
|
|
|
|
// https://developer.paypal.com/docs/api/subscriptions/v1/#definition-plan_override
|
|
PlanOverride struct {
|
|
BillingCycles []BillingCycleOverride `json:"billing_cycles,omitempty"`
|
|
PaymentPreferences *PaymentPreferencesOverride `json:"payment_preferences,omitempty"`
|
|
Taxes *TaxesOverride `json:"taxes,omitempty"`
|
|
}
|
|
|
|
// https://developer.paypal.com/docs/api/subscriptions/v1/#definition-payment_preferences_override
|
|
PaymentPreferencesOverride struct {
|
|
AutoBillOutstanding bool `json:"auto_bill_outstanding,omitempty"`
|
|
SetupFee Money `json:"setup_fee,omitempty"`
|
|
SetupFeeFailureAction SetupFeeFailureAction `json:"setup_fee_failure_action,omitempty"`
|
|
PaymentFailureThreshold int `json:"payment_failure_threshold,omitempty"`
|
|
}
|
|
|
|
// https://developer.paypal.com/docs/api/subscriptions/v1/#definition-payment_preferences_override
|
|
TaxesOverride struct {
|
|
Percentage string `json:"percentage,omitempty"`
|
|
Inclusive *bool `json:"inclusive,omitempty"`
|
|
}
|
|
|
|
// https://developer.paypal.com/docs/api/subscriptions/v1/#definition-billing_cycle_override
|
|
BillingCycleOverride struct {
|
|
PricingScheme PricingScheme `json:"pricing_scheme,omitempty"`
|
|
Sequence *int `json:"sequence,omitempty"`
|
|
TotalCycles *int `json:"total_cycles,omitempty"`
|
|
}
|
|
)
|
|
|
|
func (p *Subscription) GetUpdatePatch() []Patch {
|
|
result := []Patch{
|
|
{
|
|
Operation: "replace",
|
|
Path: "/billing_info/outstanding_balance",
|
|
Value: p.BillingInfo.OutstandingBalance,
|
|
},
|
|
}
|
|
return result
|
|
}
|
|
|
|
// CreateSubscriptionPlan creates a subscriptionPlan
|
|
// Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_create
|
|
// Endpoint: POST /v1/billing/subscriptions
|
|
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 {
|
|
return response, err
|
|
}
|
|
err = c.SendWithAuth(req, response)
|
|
return response, err
|
|
}
|
|
|
|
// 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(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
|
|
}
|
|
err = c.SendWithAuth(req, nil)
|
|
return err
|
|
}
|
|
|
|
// GetSubscriptionDetails shows details for a subscription, by ID.
|
|
// Endpoint: GET /v1/billing/subscriptions/
|
|
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
|
|
}
|
|
err = c.SendWithAuth(req, response)
|
|
return response, err
|
|
}
|
|
|
|
// 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(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
|
|
}
|
|
err = c.SendWithAuth(req, nil)
|
|
return 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(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
|
|
}
|
|
err = c.SendWithAuth(req, nil)
|
|
return err
|
|
}
|
|
|
|
// 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(ctx context.Context, subscriptionId string, request CaptureRequest) (*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
|
|
}
|
|
err = c.SendWithAuth(req, response)
|
|
return response, err
|
|
}
|
|
|
|
// 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(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
|
|
}
|
|
err = c.SendWithAuth(req, nil)
|
|
return err
|
|
}
|
|
|
|
// 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(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.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
|
|
}
|
|
|
|
err = c.SendWithAuth(req, response)
|
|
return response, err
|
|
}
|
|
|
|
// 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(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
|
|
}
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
err = c.SendWithAuth(req, response)
|
|
|
|
return response, err
|
|
}
|