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  }