@lap v0.3
# Machine-readable API spec. Each @endpoint block is one API call.
@api Subscriptions
@base https://api-m.sandbox.paypal.com
@version 1.8
@auth OAuth2
@endpoints 16
@toc billing(16)

@endpoint POST /v1/billing/plans
@desc Create plan
@required {product_id: str # The ID of the product created through Catalog Products API., name: str # The plan name., billing_cycles: [map{pricing_scheme: map, frequency!: map, tenure_type!: str, sequence!: int, total_cycles: int}] # An array of billing cycles for trial billing and regular billing. A plan can have at most two trial cycles and only one regular cycle., payment_preferences: map{auto_bill_outstanding: bool, setup_fee: map, setup_fee_failure_action: str, payment_failure_threshold: int} # The payment preferences for a subscription.}
@optional {Prefer: str=return=minimal # The preferred server response upon successful completion of the request. Value is:return=minimal. The server returns a minimal response to optimize communication between the API caller and the server. A minimal response includes the id, status and HATEOAS links.return=representation. The server returns a complete resource representation, including the current state of the resource., PayPal-Request-Id: str # The server stores keys for 72 hours., status: str(CREATED/INACTIVE/ACTIVE)=ACTIVE # The initial state of the plan. Allowed input values are CREATED and ACTIVE., description: str # The detailed description of the plan., taxes: map{percentage!: str(ppaas_common_percentage_v2), inclusive: bool} # The tax details., quantity_supported: bool=false # Indicates whether you can subscribe to this plan by providing a quantity for the goods or service.}
@returns(200) {id: str, product_id: str, name: str, status: str, description: str, billing_cycles: [map], payment_preferences: map{auto_bill_outstanding: bool, setup_fee: map{currency_code: str(ppaas_common_currency_code_v2), value: str}, setup_fee_failure_action: str, payment_failure_threshold: int}, taxes: map{percentage: str(ppaas_common_percentage_v2), inclusive: bool}, quantity_supported: bool, create_time: str(ppaas_date_time_v3), update_time: str(ppaas_date_time_v3), links: [map]} # A successful request returns the HTTP `200 OK` status code and a JSON response body that shows billing plan details.
@returns(201) {id: str, product_id: str, name: str, status: str, description: str, billing_cycles: [map], payment_preferences: map{auto_bill_outstanding: bool, setup_fee: map{currency_code: str(ppaas_common_currency_code_v2), value: str}, setup_fee_failure_action: str, payment_failure_threshold: int}, taxes: map{percentage: str(ppaas_common_percentage_v2), inclusive: bool}, quantity_supported: bool, create_time: str(ppaas_date_time_v3), update_time: str(ppaas_date_time_v3), links: [map]} # A successful request returns the HTTP `201 Created` status code and a JSON response body that shows billing plan details.
@errors {400: Bad Request. Request is not well-formed, syntactically incorrect, or violates schema., 401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 422: The requested action could not be performed, semantically incorrect, or failed business validation., 500: An internal server error has occurred.}
@example_request {"product_id":"PROD-XXCD1234QWER65782","name":"Video Streaming Service Plan","description":"Video Streaming Service basic plan","status":"ACTIVE","billing_cycles":[{"frequency":{"interval_unit":"MONTH","interval_count":1},"tenure_type":"TRIAL","sequence":1,"total_cycles":2,"pricing_scheme":{"fixed_price":{"value":"3","currency_code":"USD"}}},{"frequency":{"interval_unit":"MONTH","interval_count":1},"tenure_type":"TRIAL","sequence":2,"total_cycles":3,"pricing_scheme":{"fixed_price":{"value":"6","currency_code":"USD"}}},{"frequency":{"interval_unit":"MONTH","interval_count":1},"tenure_type":"REGULAR","sequence":3,"total_cycles":12,"pricing_scheme":{"fixed_price":{"value":"10","currency_code":"USD"}}}],"payment_preferences":{"auto_bill_outstanding":true,"setup_fee":{"value":"10","currency_code":"USD"},"setup_fee_failure_action":"CONTINUE","payment_failure_threshold":3},"taxes":{"percentage":"10","inclusive":false}}

@endpoint GET /v1/billing/plans
@desc List plans
@optional {Prefer: str=return=minimal # The preferred server response upon successful completion of the request. Value is:return=minimal. The server returns a minimal response to optimize communication between the API caller and the server. A minimal response includes the id, status and HATEOAS links.return=representation. The server returns a complete resource representation, including the current state of the resource., product_id: str # Filters the response by a Product ID., page_size: int=10 # The number of items to return in the response., page: int=1 # A non-zero integer which is the start index of the entire list of items to return in the response. The combination of `page=1` and `page_size=20` returns the first 20 items. The combination of `page=2` and `page_size=20` returns the next 20 items., total_required: bool=false # Indicates whether to show the total count in the response.}
@returns(200) {plans: [map], total_items: int, total_pages: int, links: [map]} # A successful request returns the HTTP `200 OK` status code and a JSON response body that lists billing plans.
@errors {400: Request is not well-formed, syntactically incorrect, or violates schema., 401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 404: The specified resource does not exist., 500: An internal server error has occurred.}

@endpoint GET /v1/billing/plans/{id}
@desc Show plan details
@required {id: str # The ID of the subscription.}
@returns(200) {id: str, product_id: str, name: str, status: str, description: str, billing_cycles: [map], payment_preferences: map{auto_bill_outstanding: bool, setup_fee: map{currency_code: str(ppaas_common_currency_code_v2), value: str}, setup_fee_failure_action: str, payment_failure_threshold: int}, taxes: map{percentage: str(ppaas_common_percentage_v2), inclusive: bool}, quantity_supported: bool, create_time: str(ppaas_date_time_v3), update_time: str(ppaas_date_time_v3), links: [map]} # A successful request returns the HTTP `200 OK` status code and a JSON response body that shows plan details.
@errors {401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 404: The specified resource does not exist., 500: An internal server error has occurred.}

@endpoint PATCH /v1/billing/plans/{id}
@desc Update plan
@required {id: str # The ID of the subscription.}
@returns(204) A successful request returns the HTTP `204 No Content` status code with no JSON response body.
@errors {400: Request is not well-formed, syntactically incorrect, or violates schema., 401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 404: The specified resource does not exist., 422: The requested action could not be performed, semantically incorrect, or failed business validation., 500: An internal server error has occurred.}

@endpoint POST /v1/billing/plans/{id}/activate
@desc Activate plan
@required {id: str # The ID of the subscription.}
@returns(204) A successful request returns the HTTP `204 No Content` status code with no JSON response body.
@errors {401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 404: The specified resource does not exist., 422: The requested action could not be performed, semantically incorrect, or failed business validation., 500: An internal server error has occurred.}

@endpoint POST /v1/billing/plans/{id}/deactivate
@desc Deactivate plan
@required {id: str # The ID of the subscription.}
@returns(204) A successful request returns the HTTP `204 No Content` status code with no JSON response body.
@errors {401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 404: The specified resource does not exist., 422: The requested action could not be performed, semantically incorrect, or failed business validation., 500: An internal server error has occurred.}

@endpoint POST /v1/billing/plans/{id}/update-pricing-schemes
@desc Update pricing
@required {id: str # The ID of the subscription., pricing_schemes: [map{billing_cycle_sequence!: int, pricing_scheme!: map}] # An array of pricing schemes.}
@returns(204) A successful request returns the HTTP `204 No Content` status code with no JSON response body.
@errors {400: Bad Request. Request is not well-formed, syntactically incorrect, or violates schema., 401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 404: The specified resource does not exist., 422: The requested action could not be performed, semantically incorrect, or failed business validation., 500: An internal server error has occurred.}
@example_request {"pricing_schemes":[{"billing_cycle_sequence":1,"pricing_scheme":{"fixed_price":{"value":"50","currency_code":"USD"}}},{"billing_cycle_sequence":2,"pricing_scheme":{"fixed_price":{"value":"100","currency_code":"USD"},"pricing_model":"VOLUME","tiers":[{"starting_quantity":"1","ending_quantity":"1000","amount":{"value":"150","currency_code":"USD"}},{"starting_quantity":"1001","amount":{"value":"250","currency_code":"USD"}}]}}]}

@endpoint POST /v1/billing/subscriptions
@desc Create subscription
@required {plan_id: str # The ID of the plan.}
@optional {Prefer: str=return=minimal # The preferred server response upon successful completion of the request. Value is:return=minimal. The server returns a minimal response to optimize communication between the API caller and the server. A minimal response includes the id, status and HATEOAS links.return=representation. The server returns a complete resource representation, including the current state of the resource., PayPal-Request-Id: str # The server stores keys for 72 hours., start_time: str(ppaas_date_time_v3) # The date and time, in [Internet date and time format](https://tools.ietf.org/html/rfc3339#section-5.6). Seconds are required while fractional seconds are optional.Note: The regular expression provides guidance but does not reject all invalid dates., quantity: str # The quantity of the product in the subscription., shipping_amount: map{currency_code!: str(ppaas_common_currency_code_v2), value!: str} # The currency and amount for a financial transaction, such as a balance or payment due., subscriber: any, auto_renewal: bool=false # DEPRECATED. Indicates whether the subscription auto-renews after the billing cycles complete., application_context: map{brand_name: str, locale: str(ppaas_common_language_v3), shipping_preference: str, user_action: str, payment_method: map, return_url!: str(uri), cancel_url!: str(uri)} # The application context, which customizes the payer experience during the subscription approval process with PayPal., custom_id: str # The custom id for the subscription. Can be invoice id., plan: map{billing_cycles: [map], payment_preferences: map, taxes: map} # An inline plan object to customise the subscription. You can override plan level default attributes by providing customised values for the subscription in this object., merchant_inventory: any}
@returns(200) A successful request returns the HTTP `200 OK` status code and a JSON response body that shows subscription details.
@returns(201) A successful request returns the HTTP `201 Created` status code and a JSON response body that shows subscription details.
@errors {400: Bad Request. Request is not well-formed, syntactically incorrect, or violates schema., 401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 422: The requested action could not be performed, semantically incorrect, or failed business validation., 500: An internal server error has occurred.}
@example_request {"plan_id":"P-5ML4271244454362WXNWU5NQ","start_time":"2018-11-01T00:00:00Z","quantity":"20","shipping_amount":{"currency_code":"USD","value":"10.00"},"subscriber":{"name":{"given_name":"John","surname":"Doe"},"email_address":"customer@example.com","shipping_address":{"name":{"full_name":"John Doe"},"address":{"address_line_1":"2211 N First Street","address_line_2":"Building 17","admin_area_2":"San Jose","admin_area_1":"CA","postal_code":"95131","country_code":"US"}}},"application_context":{"brand_name":"walmart","locale":"en-US","shipping_preference":"SET_PROVIDED_ADDRESS","user_action":"SUBSCRIBE_NOW","payment_method":{"payer_selected":"PAYPAL","payee_preferred":"IMMEDIATE_PAYMENT_REQUIRED"},"return_url":"https://example.com/returnUrl","cancel_url":"https://example.com/cancelUrl"}}

@endpoint GET /v1/billing/subscriptions/{id}
@desc Show subscription details
@required {id: str # The ID of the subscription.}
@optional {fields: str # List of fields that are to be returned in the response. Possible value for fields are last_failed_payment and plan.}
@returns(200) A successful request returns the HTTP `200 OK` status code and a JSON response body that shows subscription details.
@errors {401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 404: The specified resource does not exist., 500: An internal server error has occurred.}

@endpoint PATCH /v1/billing/subscriptions/{id}
@desc Update subscription
@required {id: str # The ID of the subscription.}
@returns(204) A successful request returns the HTTP `204 No Content` status code with no JSON response body.
@errors {400: Request is not well-formed, syntactically incorrect, or violates schema., 401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 404: The specified resource does not exist., 422: The requested action could not be performed, semantically incorrect, or failed business validation., 500: An internal server error has occurred.}

@endpoint POST /v1/billing/subscriptions/{id}/revise
@desc Revise plan or quantity of subscription
@required {id: str # The ID of the subscription.}
@optional {plan_id: str # The unique PayPal-generated ID for the plan., quantity: str # The quantity of the product or service in the subscription., shipping_amount: map{currency_code!: str(ppaas_common_currency_code_v2), value!: str} # The currency and amount for a financial transaction, such as a balance or payment due., shipping_address: map{name: map, type: str, options: [map], address: map} # The shipping details., application_context: map{brand_name: str, locale: str(ppaas_common_language_v3), shipping_preference: str, payment_method: map, return_url!: str(uri), cancel_url!: str(uri)} # The application context, which customizes the payer experience during the subscription approval process with PayPal., plan: map{billing_cycles: [map], payment_preferences: map, taxes: map} # An inline plan object to customise the subscription. You can override plan level default attributes by providing customised values for the subscription in this object.}
@returns(200) {plan_id: str, quantity: str, shipping_amount: map{currency_code: str(ppaas_common_currency_code_v2), value: str}, shipping_address: map{name: map{full_name: str}, type: str, options: [map], address: map{address_line_1: str, address_line_2: str, admin_area_2: str, admin_area_1: str, postal_code: str, country_code: str(ppaas_common_country_code_v2)}}, plan: map{billing_cycles: [map], payment_preferences: map{auto_bill_outstanding: bool, setup_fee: map{currency_code: str(ppaas_common_currency_code_v2), value: str}, setup_fee_failure_action: str, payment_failure_threshold: int}, taxes: map{percentage: str(ppaas_common_percentage_v2), inclusive: bool}}, plan_overridden: bool, links: [map]} # A successful request returns the HTTP `200 OK` status code and a JSON response body that shows subscription details.
@errors {400: Bad Request. Request is not well-formed, syntactically incorrect, or violates schema., 401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 404: The specified resource does not exist., 422: The requested action could not be performed, semantically incorrect, or failed business validation., 500: An internal server error has occurred.}
@example_request {"plan_id":"P-5ML4271244454362WXNWU5NQ","shipping_amount":{"currency_code":"USD","value":"10.00"},"shipping_address":{"name":{"full_name":"John Doe"},"address":{"address_line_1":"2211 N First Street","address_line_2":"Building 17","admin_area_2":"San Jose","admin_area_1":"CA","postal_code":"95131","country_code":"US"}},"application_context":{"brand_name":"walmart","locale":"en-US","shipping_preference":"SET_PROVIDED_ADDRESS","payment_method":{"payer_selected":"PAYPAL","payee_preferred":"IMMEDIATE_PAYMENT_REQUIRED"},"return_url":"https://example.com/returnUrl","cancel_url":"https://example.com/cancelUrl"}}

@endpoint POST /v1/billing/subscriptions/{id}/suspend
@desc Suspend subscription
@required {id: str # The ID of the subscription., reason: str # The reason for suspension of the Subscription.}
@returns(204) A successful request returns the HTTP `204 No Content` status code with no JSON response body.
@errors {400: Bad Request. Request is not well-formed, syntactically incorrect, or violates schema., 401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 404: The specified resource does not exist., 422: The requested action could not be performed, semantically incorrect, or failed business validation., 500: An internal server error has occurred.}
@example_request {"reason":"Item out of stock"}

@endpoint POST /v1/billing/subscriptions/{id}/cancel
@desc Cancel subscription
@required {id: str # The ID of the subscription., reason: str # The reason for the cancellation of a subscription.}
@returns(204) A successful request returns the HTTP `204 No Content` status code with no JSON response body.
@errors {400: Bad Request. Request is not well-formed, syntactically incorrect, or violates schema., 401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 404: The specified resource does not exist., 422: The requested action could not be performed, semantically incorrect, or failed business validation., 500: An internal server error has occurred.}
@example_request {"reason":"Not satisfied with the service"}

@endpoint POST /v1/billing/subscriptions/{id}/activate
@desc Activate subscription
@required {id: str # The ID of the subscription.}
@optional {reason: str # The reason for activation of a subscription. Required to reactivate the subscription.}
@returns(204) A successful request returns the HTTP `204 No Content` status code with no JSON response body.
@errors {400: Bad Request. Request is not well-formed, syntactically incorrect, or violates schema., 401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 404: The specified resource does not exist., 422: The requested action could not be performed, semantically incorrect, or failed business validation., 500: An internal server error has occurred.}
@example_request {"reason":"Reactivating the subscription"}

@endpoint POST /v1/billing/subscriptions/{id}/capture
@desc Capture authorized payment on subscription
@required {id: str # The ID of the subscription., note: str # The reason or note for the subscription charge., capture_type: str # The type of capture., amount: map{currency_code!: str(ppaas_common_currency_code_v2), value!: str} # The currency and amount for a financial transaction, such as a balance or payment due.}
@optional {PayPal-Request-Id: str # The server stores keys for 72 hours.}
@returns(200) {status: str, id: str, amount_with_breakdown: map{gross_amount: map{currency_code: str(ppaas_common_currency_code_v2), value: str}, total_item_amount: map{currency_code: str(ppaas_common_currency_code_v2), value: str}, fee_amount: map{currency_code: str(ppaas_common_currency_code_v2), value: str}, shipping_amount: map{currency_code: str(ppaas_common_currency_code_v2), value: str}, tax_amount: map{currency_code: str(ppaas_common_currency_code_v2), value: str}, net_amount: map{currency_code: str(ppaas_common_currency_code_v2), value: str}}, payer_name: map{prefix: str, given_name: str, surname: str, middle_name: str, suffix: str, full_name: str}, payer_email: str(ppaas_common_email_address_v2), time: str(ppaas_date_time_v3)} # A successful request returns the HTTP `200 OK` status code and a JSON response body that shows subscription details.
@returns(202) Request Accepted.
@errors {400: Bad Request. Request is not well-formed, syntactically incorrect, or violates schema., 401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 404: The specified resource does not exist., 422: The requested action could not be performed, semantically incorrect, or failed business validation., 500: An internal server error has occurred.}
@example_request {"note":"Charging as the balance reached the limit","capture_type":"OUTSTANDING_BALANCE","amount":{"currency_code":"USD","value":"100"}}

@endpoint GET /v1/billing/subscriptions/{id}/transactions
@desc List transactions for subscription
@required {id: str # The ID of the subscription., start_time: str # The start time of the range of transactions to list., end_time: str # The end time of the range of transactions to list.}
@returns(200) {transactions: [map], total_items: int, total_pages: int, links: [map]} # A successful request returns the HTTP `200 OK` status code and a JSON response body that shows subscription details.
@errors {400: Bad Request. Request is not well-formed, syntactically incorrect, or violates schema., 401: Authentication failed due to missing authorization header, or invalid authentication credentials., 403: Authorization failed due to insufficient permissions., 404: The specified resource does not exist., 500: An internal server error has occurred.}

@end
