github.com/plutov/paypal/v4@v4.7.1/subscription.go (about) 1 package paypal 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 "time" 8 ) 9 10 type ( 11 SubscriptionBase struct { 12 PlanID string `json:"plan_id"` 13 StartTime *JSONTime `json:"start_time,omitempty"` 14 EffectiveTime *JSONTime `json:"effective_time,omitempty"` 15 Quantity string `json:"quantity,omitempty"` 16 ShippingAmount *Money `json:"shipping_amount,omitempty"` 17 Subscriber *Subscriber `json:"subscriber,omitempty"` 18 AutoRenewal bool `json:"auto_renewal,omitempty"` 19 ApplicationContext *ApplicationContext `json:"application_context,omitempty"` 20 CustomID string `json:"custom_id,omitempty"` 21 Plan *PlanOverride `json:"plan,omitempty"` 22 } 23 24 SubscriptionDetails struct { 25 ID string `json:"id,omitempty"` 26 SubscriptionStatus SubscriptionStatus `json:"status,omitempty"` 27 SubscriptionStatusChangeNote string `json:"status_change_note,omitempty"` 28 StatusUpdateTime time.Time `json:"status_update_time,omitempty"` 29 } 30 31 Subscription struct { 32 SubscriptionDetailResp 33 } 34 35 // SubscriptionDetailResp struct 36 SubscriptionDetailResp struct { 37 SubscriptionBase 38 SubscriptionDetails 39 BillingInfo BillingInfo `json:"billing_info,omitempty"` // not found in documentation 40 SharedResponse 41 } 42 43 SubscriptionCaptureResponse struct { 44 Status SubscriptionTransactionStatus `json:"status"` 45 Id string `json:"id"` 46 AmountWithBreakdown AmountWithBreakdown `json:"amount_with_breakdown"` 47 PayerName Name `json:"payer_name"` 48 PayerEmail string `json:"payer_email"` 49 Time time.Time `json:"time"` 50 } 51 52 //Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#definition-amount_with_breakdown 53 AmountWithBreakdown struct { 54 GrossAmount Money `json:"gross_amount"` 55 FeeAmount Money `json:"fee_amount"` 56 ShippingAmount Money `json:"shipping_amount"` 57 TaxAmount Money `json:"tax_amount"` 58 NetAmount Money `json:"net_amount"` 59 } 60 61 SubscriptionTransactionsParams struct { 62 SubscriptionId string 63 StartTime time.Time 64 EndTime time.Time 65 } 66 67 SubscriptionTransactionsResponse struct { 68 Transactions []SubscriptionCaptureResponse `json:"transactions"` 69 SharedListResponse 70 } 71 72 CaptureRequest struct { 73 Note string `json:"note"` 74 CaptureType CaptureType `json:"capture_type"` 75 Amount Money `json:"amount"` 76 } 77 78 // https://developer.paypal.com/docs/api/subscriptions/v1/#definition-plan_override 79 PlanOverride struct { 80 BillingCycles []BillingCycleOverride `json:"billing_cycles,omitempty"` 81 PaymentPreferences *PaymentPreferencesOverride `json:"payment_preferences,omitempty"` 82 Taxes *TaxesOverride `json:"taxes,omitempty"` 83 } 84 85 // https://developer.paypal.com/docs/api/subscriptions/v1/#definition-payment_preferences_override 86 PaymentPreferencesOverride struct { 87 AutoBillOutstanding bool `json:"auto_bill_outstanding,omitempty"` 88 SetupFee Money `json:"setup_fee,omitempty"` 89 SetupFeeFailureAction SetupFeeFailureAction `json:"setup_fee_failure_action,omitempty"` 90 PaymentFailureThreshold int `json:"payment_failure_threshold,omitempty"` 91 } 92 93 // https://developer.paypal.com/docs/api/subscriptions/v1/#definition-payment_preferences_override 94 TaxesOverride struct { 95 Percentage string `json:"percentage,omitempty"` 96 Inclusive *bool `json:"inclusive,omitempty"` 97 } 98 99 // https://developer.paypal.com/docs/api/subscriptions/v1/#definition-billing_cycle_override 100 BillingCycleOverride struct { 101 PricingScheme PricingScheme `json:"pricing_scheme,omitempty"` 102 Sequence *int `json:"sequence,omitempty"` 103 TotalCycles *int `json:"total_cycles,omitempty"` 104 } 105 ) 106 107 func (self *Subscription) GetUpdatePatch() []Patch { 108 result := []Patch{ 109 { 110 Operation: "replace", 111 Path: "/billing_info/outstanding_balance", 112 Value: self.BillingInfo.OutstandingBalance, 113 }, 114 } 115 return result 116 } 117 118 // CreateSubscriptionPlan creates a subscriptionPlan 119 // Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_create 120 // Endpoint: POST /v1/billing/subscriptions 121 func (c *Client) CreateSubscription(ctx context.Context, newSubscription SubscriptionBase) (*SubscriptionDetailResp, error) { 122 req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s%s", c.APIBase, "/v1/billing/subscriptions"), newSubscription) 123 req.Header.Add("Prefer", "return=representation") 124 response := &SubscriptionDetailResp{} 125 if err != nil { 126 return response, err 127 } 128 err = c.SendWithAuth(req, response) 129 return response, err 130 } 131 132 // UpdateSubscriptionPlan. updates a plan 133 // Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_patch 134 // Endpoint: PATCH /v1/billing/subscriptions/:subscription_id 135 func (c *Client) UpdateSubscription(ctx context.Context, updatedSubscription Subscription) error { 136 req, err := c.NewRequest(ctx, http.MethodPatch, fmt.Sprintf("%s%s%s", c.APIBase, "/v1/billing/subscriptions/", updatedSubscription.ID), updatedSubscription.GetUpdatePatch()) 137 if err != nil { 138 return err 139 } 140 err = c.SendWithAuth(req, nil) 141 return err 142 } 143 144 // GetSubscriptionDetails shows details for a subscription, by ID. 145 // Endpoint: GET /v1/billing/subscriptions/ 146 func (c *Client) GetSubscriptionDetails(ctx context.Context, subscriptionID string) (*SubscriptionDetailResp, error) { 147 req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/v1/billing/subscriptions/%s", c.APIBase, subscriptionID), nil) 148 response := &SubscriptionDetailResp{} 149 if err != nil { 150 return response, err 151 } 152 err = c.SendWithAuth(req, response) 153 return response, err 154 } 155 156 // Activates the subscription. 157 // Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_activate 158 // Endpoint: POST /v1/billing/subscriptions/{id}/activate 159 func (c *Client) ActivateSubscription(ctx context.Context, subscriptionId, activateReason string) error { 160 req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s/v1/billing/subscriptions/%s/activate", c.APIBase, subscriptionId), map[string]string{"reason": activateReason}) 161 if err != nil { 162 return err 163 } 164 err = c.SendWithAuth(req, nil) 165 return err 166 } 167 168 // Cancels the subscription. 169 // Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_cancel 170 // Endpoint: POST /v1/billing/subscriptions/{id}/cancel 171 func (c *Client) CancelSubscription(ctx context.Context, subscriptionId, cancelReason string) error { 172 req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s/v1/billing/subscriptions/%s/cancel", c.APIBase, subscriptionId), map[string]string{"reason": cancelReason}) 173 if err != nil { 174 return err 175 } 176 err = c.SendWithAuth(req, nil) 177 return err 178 } 179 180 // Captures an authorized payment from the subscriber on the subscription. 181 // Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_capture 182 // Endpoint: POST /v1/billing/subscriptions/{id}/capture 183 func (c *Client) CaptureSubscription(ctx context.Context, subscriptionId string, request CaptureRequest) (*SubscriptionCaptureResponse, error) { 184 req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s/v1/billing/subscriptions/%s/capture", c.APIBase, subscriptionId), request) 185 response := &SubscriptionCaptureResponse{} 186 if err != nil { 187 return response, err 188 } 189 err = c.SendWithAuth(req, response) 190 return response, err 191 } 192 193 // Suspends the subscription. 194 // Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_suspend 195 // Endpoint: POST /v1/billing/subscriptions/{id}/suspend 196 func (c *Client) SuspendSubscription(ctx context.Context, subscriptionId, reason string) error { 197 req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s/v1/billing/subscriptions/%s/suspend", c.APIBase, subscriptionId), map[string]string{"reason": reason}) 198 if err != nil { 199 return err 200 } 201 err = c.SendWithAuth(req, nil) 202 return err 203 } 204 205 // Lists transactions for a subscription. 206 // Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_transactions 207 // Endpoint: GET /v1/billing/subscriptions/{id}/transactions 208 func (c *Client) GetSubscriptionTransactions(ctx context.Context, requestParams SubscriptionTransactionsParams) (*SubscriptionTransactionsResponse, error) { 209 startTime := requestParams.StartTime.Format("2006-01-02T15:04:05Z") 210 endTime := requestParams.EndTime.Format("2006-01-02T15:04:05Z") 211 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) 212 response := &SubscriptionTransactionsResponse{} 213 if err != nil { 214 return response, err 215 } 216 217 err = c.SendWithAuth(req, response) 218 return response, err 219 } 220 221 // Revise plan or quantity of subscription 222 // Doc: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_revise 223 // Endpoint: POST /v1/billing/subscriptions/{id}/revise 224 func (c *Client) ReviseSubscription(ctx context.Context, subscriptionId string, reviseSubscription SubscriptionBase) (*SubscriptionDetailResp, error) { 225 req, err := c.NewRequest(ctx, http.MethodPost, fmt.Sprintf("%s/v1/billing/subscriptions/%s/revise", c.APIBase, subscriptionId), reviseSubscription) 226 response := &SubscriptionDetailResp{} 227 if err != nil { 228 return response, err 229 } 230 231 req.Header.Add("Content-Type", "application/json") 232 err = c.SendWithAuth(req, response) 233 234 return response, err 235 }