mirror of
https://github.com/mautrix/signal.git
synced 2026-09-17 08:12:05 -04:00
441 lines
21 KiB
Protocol Buffer
441 lines
21 KiB
Protocol Buffer
|
|
/*
|
||
|
|
* Copyright 2026 Signal Messenger, LLC
|
||
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||
|
|
*/
|
||
|
|
|
||
|
|
syntax = "proto3";
|
||
|
|
|
||
|
|
option java_multiple_files = true;
|
||
|
|
|
||
|
|
package org.signal.chat.purchase;
|
||
|
|
|
||
|
|
import "google/protobuf/empty.proto";
|
||
|
|
import "org/signal/chat/common.proto";
|
||
|
|
import "org/signal/chat/require.proto";
|
||
|
|
import "org/signal/chat/errors.proto";
|
||
|
|
import "org/signal/chat/tag.proto";
|
||
|
|
|
||
|
|
// Service for creating donation subscriptions
|
||
|
|
//
|
||
|
|
// Configuration for subscription levels can be found in ProductConfiguration.
|
||
|
|
service Subscriptions {
|
||
|
|
option (require.auth) = AUTH_ONLY_ANONYMOUS;
|
||
|
|
// Creates a subscriber record if it does not exist, otherwise refreshes its last access time.
|
||
|
|
|
||
|
|
// Subscribers MUST periodically hit this endpoint to update the access time on the subscription record. Subscribers
|
||
|
|
// SHOULD attempt to make an update call approximately every 3 days. Not accessing this endpoint for an extended
|
||
|
|
// period of time will result in the subscription being canceled.
|
||
|
|
rpc UpdateSubscriber(UpdateSubscriberRequest) returns (UpdateSubscriberResponse) {}
|
||
|
|
|
||
|
|
// Cancels any current subscription at the end of the current subscription period.
|
||
|
|
//
|
||
|
|
// Note: Apple IAP subscriptions do not support server-side cancellation, so this method should only be called after
|
||
|
|
// cancelling a subscription from storekit to keep server data up to date.
|
||
|
|
rpc DeleteSubscriber(DeleteSubscriberRequest) returns (DeleteSubscriberResponse) {}
|
||
|
|
|
||
|
|
// Returns a client secret that can be used to set up a new payment method with the payment processor.
|
||
|
|
rpc CreatePaymentMethod(CreatePaymentMethodRequest) returns (CreatePaymentMethodResponse) {}
|
||
|
|
|
||
|
|
// Returns a PayPal billing agreement approval URL and token that can be used to set up PayPal as a payment method.
|
||
|
|
rpc CreatePayPalPaymentMethod(CreatePayPalPaymentMethodRequest) returns (CreatePayPalPaymentMethodResponse) {}
|
||
|
|
|
||
|
|
// Sets the default payment method for a subscriber.
|
||
|
|
rpc SetDefaultPaymentMethod(SetDefaultPaymentMethodRequest) returns (SetDefaultPaymentMethodResponse) {}
|
||
|
|
|
||
|
|
// Sets the subscription level and currency for a subscriber.
|
||
|
|
rpc SetSubscriptionLevel(SetSubscriptionLevelRequest) returns (SetSubscriptionLevelResponse) {}
|
||
|
|
|
||
|
|
// Returns information about the current subscription associated with the provided subscriberId if one exists.
|
||
|
|
//
|
||
|
|
// Although it uses [Stripe's values](https://stripe.com/docs/billing/subscriptions/overview#subscription-statuses),
|
||
|
|
// the status field in the response is generic, with [Braintree-specific values](https://developer.paypal.com/braintree/docs/guides/recurring-billing/overview#subscription-statuses) mapped
|
||
|
|
// to Stripe's. Since we don't support trials or unpaid subscriptions, the associated statuses will never be returned
|
||
|
|
// by the API.
|
||
|
|
rpc GetSubscriptionInformation(GetSubscriptionInformationRequest) returns (GetSubscriptionInformationResponse) {}
|
||
|
|
|
||
|
|
// Create a receipt from a valid payment invoice that can be used to obtain an entitlement
|
||
|
|
//
|
||
|
|
// This request is repeatable so long as the ReceiptCredentialRequest remains the same. Clients should use the same
|
||
|
|
// ReceiptCredentialRequest value until they attempt to redeem the resulting ReceiptCredentialPresentation. After
|
||
|
|
// this point, the ReceiptCredentialRequest MUST NOT be reused or you may not be able to redeem a valid payment
|
||
|
|
// invoice. Clients SHOULD retry requests at this endpoint with the same ReceiptCredentialRequest value until
|
||
|
|
// receiving a response. After receiving a response, clients should then compute the ReceiptCredentialPresentation
|
||
|
|
// and redeem it at the receipt redemption endpoint. Once the first attempt is made there, the same
|
||
|
|
// ReceiptCredentialRequest MUST NOT be used again to request receipt credentials.
|
||
|
|
//
|
||
|
|
// Note that you may in fact redeem TWO or more invoices for the same ReceiptCredentialRequest while retrying this
|
||
|
|
// operation if a later invoice gets paid while you are retrying. However, the returned receipt is always for the
|
||
|
|
// latest invoice, so it will have the latest expiration possible and no entitlement time will be lost. The important
|
||
|
|
// thing is not to reuse ReceiptCredentialRequest after you have started attempting to redeem the associated
|
||
|
|
// ReceiptCredentialPresentation. Then you may produce a ReceiptCredentialPresentation for a later invoice that
|
||
|
|
// cannot be redeemed.
|
||
|
|
//
|
||
|
|
// Clients MUST validate that the generated receipt credential's level and expiration matches their expectations.
|
||
|
|
rpc GetReceiptCredentials(GetReceiptCredentialsRequest) returns (GetReceiptCredentialsResponse) {}
|
||
|
|
|
||
|
|
// Set a token that represents an IAP subscription made with App Store/Google Play Billing.
|
||
|
|
//
|
||
|
|
// To set up an App Store subscription:
|
||
|
|
// 1. Create a subscriber with UpdateSubscriber (you must regularly refresh this subscriber)
|
||
|
|
// 2. [Create a subscription](https://developer.apple.com/documentation/storekit/in-app_purchase/) with the App Store
|
||
|
|
// directly via StoreKit and obtain a originalTransactionId.
|
||
|
|
// 3. Call this RPC with the originalTransactionId
|
||
|
|
// 4. Obtain a receipt via GetReceiptCredentials which can then be used to obtain the
|
||
|
|
// entitlement
|
||
|
|
//
|
||
|
|
// Play Billing: Set a purchaseToken that represents an IAP subscription made with Google Play Billing.
|
||
|
|
//
|
||
|
|
// To set up a subscription with Google Play Billing:
|
||
|
|
// 1. Create a subscriber with UpdateSubscriber (you must regularly refresh this subscriber)
|
||
|
|
// 2. [Create a subscription](https://developer.android.com/google/play/billing/integrate) with Google Play Billing
|
||
|
|
// directly and obtain a purchaseToken. Do not [acknowledge](https://developer.android.com/google/play/billing/integrate#subscriptions)
|
||
|
|
// the purchaseToken.
|
||
|
|
// 3. Call this RPC with the purchaseToken
|
||
|
|
// 4. Obtain a receipt via GetReceiptCredentials which can then be used to obtain the
|
||
|
|
// entitlement
|
||
|
|
//
|
||
|
|
// After calling this method, the payment is confirmed. Callers must durably store their subscriberId before calling
|
||
|
|
// this method to ensure their payment is tracked.
|
||
|
|
//
|
||
|
|
// Once a purchaseToken to is posted to a subscriberId, the same subscriberId must not be used with another payment
|
||
|
|
// method. A different playbilling purchaseToken can be posted to the same subscriberId, in this case the subscription
|
||
|
|
// associated with the old purchaseToken will be cancelled.
|
||
|
|
rpc SetIapSubscription(SetIapSubscriptionRequest) returns (SetIapSubscriptionResponse) {}
|
||
|
|
|
||
|
|
// Returns a localized bank mandate for the specified bank transfer type
|
||
|
|
rpc GetBankMandate(GetBankMandateRequest) returns (GetBankMandateResponse) {}
|
||
|
|
}
|
||
|
|
|
||
|
|
message UpdateSubscriberRequest {
|
||
|
|
bytes subscriber_id = 1 [(require.exactlySize) = 32];
|
||
|
|
// A libsignal DonationPermit from rpc Donations.CreateDonationPermit.
|
||
|
|
// Not required if the subscriber already exists.
|
||
|
|
bytes donation_permit = 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
message UpdateSubscriberResponse {
|
||
|
|
oneof response {
|
||
|
|
google.protobuf.Empty success = 1;
|
||
|
|
// subscriberId authentication failure
|
||
|
|
errors.FailedUnidentifiedAuthorization subscriber_id_mismatch = 2 [(tag.reason) = "subscriber_id_mismatch"];
|
||
|
|
// The donation permit was expired or already spent
|
||
|
|
errors.FailedZkAuthentication permit_rejected = 3 [(tag.reason) = "permit_rejected"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message DeleteSubscriberRequest {
|
||
|
|
bytes subscriberId = 1 [(require.exactlySize) = 32];
|
||
|
|
}
|
||
|
|
|
||
|
|
message DeleteSubscriberResponse {
|
||
|
|
oneof response {
|
||
|
|
google.protobuf.Empty success = 1;
|
||
|
|
errors.NotFound subscriber_not_found = 2 [(tag.reason) = "subscriber_not_found"];
|
||
|
|
// The associated subscription is not a type that can be cancelled by the server. Cancel client-side, and then retry.
|
||
|
|
errors.FailedPrecondition cannot_cancel_subscription = 3 [(tag.reason) = "cannot_cancel_subscription"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
enum PaymentProvider {
|
||
|
|
PAYMENT_PROVIDER_UNKNOWN = 0;
|
||
|
|
PAYMENT_PROVIDER_STRIPE = 1;
|
||
|
|
PAYMENT_PROVIDER_BRAINTREE = 2;
|
||
|
|
PAYMENT_PROVIDER_GOOGLE_PLAY_BILLING = 3;
|
||
|
|
PAYMENT_PROVIDER_APPLE_APP_STORE = 4;
|
||
|
|
}
|
||
|
|
|
||
|
|
enum PaymentMethod {
|
||
|
|
PAYMENT_METHOD_UNKNOWN = 0;
|
||
|
|
// A credit card or debit card, including those from Apple Pay and Google Pay
|
||
|
|
PAYMENT_METHOD_CARD = 1;
|
||
|
|
// A SEPA debit account
|
||
|
|
PAYMENT_METHOD_SEPA_DEBIT = 2;
|
||
|
|
// An iDEAL account
|
||
|
|
PAYMENT_METHOD_IDEAL = 3;
|
||
|
|
// A PayPal account
|
||
|
|
PAYMENT_METHOD_PAYPAL = 4;
|
||
|
|
PAYMENT_METHOD_GOOGLE_PLAY_BILLING = 5;
|
||
|
|
PAYMENT_METHOD_APPLE_APP_STORE = 6;
|
||
|
|
}
|
||
|
|
|
||
|
|
enum SubscriptionStatus {
|
||
|
|
SUBSCRIPTION_STATUS_UNKNOWN = 0;
|
||
|
|
// The subscription is in good standing and the most recent payment was successful.
|
||
|
|
SUBSCRIPTION_STATUS_ACTIVE = 1;
|
||
|
|
// Payment failed when creating the subscription, or the subscription's start date is in the future.
|
||
|
|
SUBSCRIPTION_STATUS_INCOMPLETE = 2;
|
||
|
|
// Payment on the latest renewal failed but there are processor retries left, or payment wasn't attempted.
|
||
|
|
SUBSCRIPTION_STATUS_PAST_DUE = 3;
|
||
|
|
// The subscription has been canceled.
|
||
|
|
SUBSCRIPTION_STATUS_CANCELED = 4;
|
||
|
|
// The latest renewal hasn't been paid but the subscription remains in place.
|
||
|
|
SUBSCRIPTION_STATUS_UNPAID = 5;
|
||
|
|
}
|
||
|
|
|
||
|
|
message CreatePaymentMethodRequest {
|
||
|
|
// Only PAYMENT_METHOD_CARD, PAYMENT_METHOD_SEPA_DEBIT, and PAYMENT_METHOD_IDEAL are supported;
|
||
|
|
// other values will result in an INVALID_ARGUMENT error.
|
||
|
|
bytes subscriber_id = 1 [(require.exactlySize) = 32];
|
||
|
|
PaymentMethod payment_method = 2 [(require.specified) = true];
|
||
|
|
// a libsignal DonationPermit from rpc Donations.CreateDonationPermit
|
||
|
|
bytes donation_permit = 3 [(require.nonEmpty) = true];
|
||
|
|
}
|
||
|
|
|
||
|
|
message CreatePaymentMethodResponse {
|
||
|
|
message CreatePaymentMethodResult {
|
||
|
|
string clientSecret = 1;
|
||
|
|
PaymentProvider paymentProvider = 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
oneof response {
|
||
|
|
CreatePaymentMethodResult result = 1;
|
||
|
|
errors.NotFound subscriber_not_found = 2 [(tag.reason) = "subscriber_not_found"];
|
||
|
|
// subscriberId authentication failure
|
||
|
|
errors.FailedUnidentifiedAuthorization subscriber_id_mismatch = 3 [(tag.reason) = "subscriber_id_mismatch"];
|
||
|
|
// New payment processor does not match existing processor associated with the subscription
|
||
|
|
errors.FailedPrecondition subscription_processor_conflict = 4 [(tag.reason) = "subscription_processor_conflict"];
|
||
|
|
// The donation permit was expired or already spent
|
||
|
|
errors.FailedZkAuthentication permit_rejected = 5 [(tag.reason) = "permit_rejected"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message CreatePayPalPaymentMethodRequest {
|
||
|
|
bytes subscriberId = 1 [(require.exactlySize) = 32];
|
||
|
|
// a callback URL (e.g. an in-client URL handler) for when the user approved the payment
|
||
|
|
string returnUrl = 2;
|
||
|
|
// a callback URL (e.g. an in-client URL handler) for when the user did not approve the payment
|
||
|
|
string cancelUrl = 3;
|
||
|
|
}
|
||
|
|
|
||
|
|
message CreatePayPalPaymentMethodResponse {
|
||
|
|
message CreatePayPalPaymentMethodResult {
|
||
|
|
// a URL to open where the user may approve the payment
|
||
|
|
string approvalUrl = 1;
|
||
|
|
// an opaque PayPal payment identifier to use with SetDefaultPaymentMethodRequest
|
||
|
|
string token = 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
oneof response {
|
||
|
|
CreatePayPalPaymentMethodResult result = 1;
|
||
|
|
errors.NotFound subscriber_not_found = 2 [(tag.reason) = "subscriber_not_found"];
|
||
|
|
// subscriberId authentication failure
|
||
|
|
errors.FailedUnidentifiedAuthorization subscriber_id_mismatch = 3 [(tag.reason) = "subscriber_id_mismatch"];
|
||
|
|
// New payment processor does not match existing processor associated with the subscription
|
||
|
|
errors.FailedPrecondition subscription_processor_conflict = 4 [(tag.reason) = "subscription_processor_conflict"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetDefaultPaymentMethodRequest {
|
||
|
|
message StripePaymentMethod {
|
||
|
|
string paymentMethodToken = 1 [(require.nonEmpty) = true];
|
||
|
|
}
|
||
|
|
message BraintreePaymentMethod {
|
||
|
|
string paymentMethodToken = 1 [(require.nonEmpty) = true];
|
||
|
|
}
|
||
|
|
message SepaPaymentMethod {
|
||
|
|
string setupIntentId = 1 [(require.nonEmpty) = true];
|
||
|
|
}
|
||
|
|
|
||
|
|
bytes subscriberId = 1 [(require.exactlySize) = 32];
|
||
|
|
oneof request {
|
||
|
|
StripePaymentMethod stripe = 2;
|
||
|
|
BraintreePaymentMethod braintree = 3;
|
||
|
|
SepaPaymentMethod sepa = 4;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetDefaultPaymentMethodResponse {
|
||
|
|
oneof response {
|
||
|
|
google.protobuf.Empty success = 1;
|
||
|
|
errors.NotFound subscriber_not_found = 2 [(tag.reason) = "subscriber_not_found"];
|
||
|
|
// subscriberId authentication failure
|
||
|
|
errors.FailedUnidentifiedAuthorization subscriber_id_mismatch = 3 [(tag.reason) = "subscriber_id_mismatch"];
|
||
|
|
errors.FailedPrecondition payment_method_not_set_up = 4 [(tag.reason) = "payment_method_not_set_up"];
|
||
|
|
// Payment processor does not match existing processor associated with the subscription
|
||
|
|
errors.FailedPrecondition subscription_processor_conflict = 5 [(tag.reason) = "subscription_processor_conflict"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetSubscriptionLevelRequest {
|
||
|
|
bytes subscriberId = 1 [(require.exactlySize) = 32];
|
||
|
|
uint64 level = 2;
|
||
|
|
string currency = 3;
|
||
|
|
string idempotencyKey = 4;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Information about a charge failure.
|
||
|
|
|
||
|
|
// Meaningfully interpreting chargeFailure response fields requires inspecting the processor field first.
|
||
|
|
//
|
||
|
|
// For Stripe, code will be one of the [codes defined here](https://stripe.com/docs/api/charges/object#charge_object-failure_code),
|
||
|
|
// while message [may contain a further textual description](https://stripe.com/docs/api/charges/object#charge_object-failure_message).
|
||
|
|
// The outcome fields are optional, but present values will directly map to Stripe [response properties](https://stripe.com/docs/api/charges/object#charge_object-outcome-network_status)
|
||
|
|
//
|
||
|
|
// For Braintree, the outcome fields will be null. The code and message will contain one of
|
||
|
|
// - a processor decline code (as a string) in code, and associated text in message, as defined this [table](https://developer.paypal.com/braintree/docs/reference/general/processor-responses/authorization-responses)
|
||
|
|
// - `gateway` in code, with a [reason](https://developer.paypal.com/braintree/articles/control-panel/transactions/gateway-rejections) in message
|
||
|
|
// - `code` = "unknown", message = "unknown"
|
||
|
|
//
|
||
|
|
// IAP payment processors will never include charge failure information, and detailed order information should be
|
||
|
|
// retrieved from the payment processor directly
|
||
|
|
message ChargeFailure {
|
||
|
|
PaymentProvider processor = 1;
|
||
|
|
// See [Stripe failure codes](https://stripe.com/docs/api/charges/object#charge_object-failure_code) or
|
||
|
|
// [Braintree decline codes](https://developer.paypal.com/braintree/docs/reference/general/processor-responses/authorization-responses#decline-codes)
|
||
|
|
// depending on which processor was used
|
||
|
|
string code = 2;
|
||
|
|
// See [Stripe failure codes](https://stripe.com/docs/api/charges/object#charge_object-failure_code) or
|
||
|
|
// [Braintree decline codes](https://developer.paypal.com/braintree/docs/reference/general/processor-responses/authorization-responses#decline-codes)
|
||
|
|
// depending on which processor was used
|
||
|
|
string message = 3;
|
||
|
|
// See [Outcome Network Status](https://stripe.com/docs/api/charges/object#charge_object-outcome-network_status)
|
||
|
|
optional string outcome_network_status = 4;
|
||
|
|
// See [Outcome Reason](https://stripe.com/docs/api/charges/object#charge_object-outcome-reason)
|
||
|
|
optional string outcome_reason = 5;
|
||
|
|
// See [Outcome Type](https://stripe.com/docs/api/charges/object#charge_object-outcome-type)
|
||
|
|
optional string outcome_type = 6;
|
||
|
|
}
|
||
|
|
|
||
|
|
message PaymentRequired {
|
||
|
|
optional ChargeFailure charge_failure = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetSubscriptionLevelResponse {
|
||
|
|
message SetSubscriptionLevelResult {
|
||
|
|
uint64 level = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
oneof response {
|
||
|
|
SetSubscriptionLevelResult success = 1;
|
||
|
|
errors.NotFound subscriber_not_found = 2 [(tag.reason) = "subscriber_not_found"];
|
||
|
|
// subscriberId authentication failure
|
||
|
|
errors.FailedUnidentifiedAuthorization subscriber_id_mismatch = 3 [(tag.reason) = "subscriber_id_mismatch"];
|
||
|
|
// New payment processor does not match existing processor associated with the subscription
|
||
|
|
errors.FailedPrecondition subscription_processor_conflict = 4 [(tag.reason) = "subscription_processor_conflict"];
|
||
|
|
errors.FailedPrecondition payment_method_not_set_up = 5 [(tag.reason) = "payment_method_not_set_up"];
|
||
|
|
// The payment processor does not support this operation
|
||
|
|
errors.FailedPrecondition unsupported_operation = 6 [(tag.reason) = "unsupported_operation"];
|
||
|
|
// The requested level was invalid
|
||
|
|
errors.FailedPrecondition unsupported_level = 7 [(tag.reason) = "unsupported_level"];
|
||
|
|
// The requested currency was invalid
|
||
|
|
errors.FailedPrecondition unsupported_currency = 8 [(tag.reason) = "unsupported_currency"];
|
||
|
|
// The card could not be charged
|
||
|
|
errors.FailedPrecondition payment_requires_action = 9 [(tag.reason) = "payment_requires_action"];
|
||
|
|
// Cannot transition from existing level to the requested level
|
||
|
|
errors.FailedPrecondition invalid_level_transition = 10 [(tag.reason) = "invalid_level_transition"];
|
||
|
|
// The idempotency key was invalid or re-used with a modified request
|
||
|
|
errors.FailedPrecondition invalid_idempotency_key = 11 [(tag.reason) = "invalid_idempotency_key"];
|
||
|
|
// The payment failed; see charge failure details
|
||
|
|
ChargeFailure charge_failure = 12 [(tag.reason) = "charge_failure"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetIapSubscriptionRequest {
|
||
|
|
message AppStorePurchase {
|
||
|
|
string original_transaction_id = 1 [(require.nonEmpty) = true];
|
||
|
|
}
|
||
|
|
message PlayBillingPurchase {
|
||
|
|
string purchase_token = 1 [(require.nonEmpty) = true];
|
||
|
|
}
|
||
|
|
|
||
|
|
bytes subscriberId = 1 [(require.exactlySize) = 32];
|
||
|
|
oneof request {
|
||
|
|
AppStorePurchase app_store = 2;
|
||
|
|
PlayBillingPurchase play_billing = 3;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message SetIapSubscriptionResponse {
|
||
|
|
message SetIapSubscriptionResult {
|
||
|
|
uint64 level = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
oneof response {
|
||
|
|
SetIapSubscriptionResult success = 1;
|
||
|
|
errors.NotFound subscriber_not_found = 2 [(tag.reason) = "subscriber_not_found"];
|
||
|
|
// subscriberId authentication failure
|
||
|
|
errors.FailedUnidentifiedAuthorization subscriber_id_mismatch = 3 [(tag.reason) = "subscriber_id_mismatch"];
|
||
|
|
// New payment processor does not match existing processor associated with the subscription
|
||
|
|
errors.FailedPrecondition subscription_processor_conflict = 4 [(tag.reason) = "subscription_processor_conflict"];
|
||
|
|
errors.FailedPrecondition payment_required = 5 [(tag.reason) = "payment_required"];
|
||
|
|
errors.FailedPrecondition invalid_transaction = 6 [(tag.reason) = "invalid_transaction"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetReceiptCredentialsRequest {
|
||
|
|
bytes subscriberId = 1 [(require.exactlySize) = 32];
|
||
|
|
bytes receiptCredentialRequest = 2 [(require.exactlySize) = 97];
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetReceiptCredentialsResponse {
|
||
|
|
message GetReceiptCredentialsResult {
|
||
|
|
bytes receiptCredentialResponse = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
oneof response {
|
||
|
|
GetReceiptCredentialsResult success = 1;
|
||
|
|
errors.NotFound subscriber_not_found = 2 [(tag.reason) = "subscriber_not_found"];
|
||
|
|
// subscriberId authentication failure
|
||
|
|
errors.FailedUnidentifiedAuthorization subscriber_id_mismatch = 3 [(tag.reason) = "subscriber_id_mismatch"];
|
||
|
|
// No invoice has been issued for this subscription OR invoice is in 'draft' or 'open' state
|
||
|
|
errors.FailedPrecondition no_paid_invoice = 4 [(tag.reason) = "no_paid_invoice"];
|
||
|
|
// Invoice is in any state other than 'draft', 'open', or 'paid'; Charge failure details may be present
|
||
|
|
PaymentRequired payment_required = 5 [(tag.reason) = "payment_required"];
|
||
|
|
// Latest paid receipt on subscription was already redeemed for a receipt credential but with a different GetReceiptCredentialRequest
|
||
|
|
errors.FailedPrecondition already_redeemed = 6 [(tag.reason) = "already_redeemed"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetSubscriptionInformationRequest {
|
||
|
|
bytes subscriberId = 1 [(require.exactlySize) = 32];
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetSubscriptionInformationResponse {
|
||
|
|
message Subscription {
|
||
|
|
// The subscription level
|
||
|
|
uint64 level = 1;
|
||
|
|
// If present, UNIX Epoch Timestamp in seconds, can be used to calculate next billing date.
|
||
|
|
optional uint64 billing_cycle_anchor = 2;
|
||
|
|
// UNIX Epoch Timestamp in seconds, when the current subscription period ends
|
||
|
|
uint64 end_of_current_period = 3;
|
||
|
|
// Whether there is a currently active subscription
|
||
|
|
bool active = 4;
|
||
|
|
// If true, an active subscription will not auto-renew at the end of the current period
|
||
|
|
bool cancel_at_period_end = 5;
|
||
|
|
// A three-letter ISO 4217 currency code for currency used in the subscription
|
||
|
|
string currency = 6;
|
||
|
|
// The amount paid for the subscription in the currency's smallest unit
|
||
|
|
uint64 amount = 7;
|
||
|
|
// The subscription's status, mapped to Stripe's statuses. trialing will never be returned
|
||
|
|
SubscriptionStatus status = 8;
|
||
|
|
// The payment provider associated with the subscription
|
||
|
|
PaymentProvider processor = 9;
|
||
|
|
// The payment method associated with the subscription
|
||
|
|
PaymentMethod payment_method = 10;
|
||
|
|
// Whether the latest charge for the subscription is in a non-terminal state
|
||
|
|
bool payment_processing = 11;
|
||
|
|
// if present, contains information that may be interpreted to help the user fix a failure
|
||
|
|
optional ChargeFailure charge_failure = 12;
|
||
|
|
}
|
||
|
|
|
||
|
|
oneof response {
|
||
|
|
Subscription success = 1;
|
||
|
|
google.protobuf.Empty no_subscription = 2;
|
||
|
|
errors.NotFound subscriber_not_found = 3 [(tag.reason) = "subscriber_not_found"];
|
||
|
|
// subscriberId authentication failure
|
||
|
|
errors.FailedUnidentifiedAuthorization subscriber_id_mismatch = 4 [(tag.reason) = "subscriber_id_mismatch"];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
enum BankTransferType {
|
||
|
|
BANK_TRANSFER_TYPE_UNKNOWN = 0;
|
||
|
|
BANK_TRANSFER_TYPE_SEPA_DEBIT = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetBankMandateRequest {
|
||
|
|
BankTransferType bank_transfer_type = 1 [(require.specified) = true];
|
||
|
|
}
|
||
|
|
|
||
|
|
message GetBankMandateResponse {
|
||
|
|
string mandate = 1;
|
||
|
|
}
|