Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ import "google/protobuf/timestamp.proto";
import "sentry_protos/billing/v1/common/v1/address.proto";
import "sentry_protos/billing/v1/common/v1/external_billing_provider.proto";

enum InvoiceKind {
// Invoices written before kinds existed; these are all contract invoices.
INVOICE_KIND_UNSPECIFIED = 0;
// Created or rolled over alongside a contract.
INVOICE_KIND_CONTRACT = 1;
// Billed to an organization outside of any contract, charged immediately.
INVOICE_KIND_ONE_OFF = 2;
}

// This is not the same as LineItemDetails, it includes
// items not related to the package such as tax. Each line item may carry an
// optional type that classifies it (e.g. "tax") so consumers can treat it
Expand All @@ -17,6 +26,9 @@ message InvoiceLineItem {
// Optional classifier for the line item, e.g. "tax". Unset for ordinary
// priced line items.
optional string type = 3;
// Caller-defined identifier for what this line bills, set on one-off
// invoice lines. Opaque to the platform.
optional string external_id = 4;
}

message Invoice {
Expand Down Expand Up @@ -52,4 +64,15 @@ message Invoice {
// (e.g. pre-migration shadow rollovers and the $0 migration stub). Default
// false means the invoice is visible on receipts.
bool hide_from_customer_receipts = 15;

InvoiceKind kind = 16;

// Caller-supplied key that makes one-off invoice creation safe to retry.
// Unique per organization and client_id; unset on contract invoices.
optional string idempotency_key = 17;

// Identifies the service that requested a one-off invoice, so it can
// recognize its own invoices and map idempotency_key back to its own
// records. Unset on contract invoices.
optional string client_id = 18;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package sentry_protos.billing.v1.services.events.v1;
import "google/protobuf/timestamp.proto";
import "sentry_protos/billing/v1/services/events/v1/billing_alert_evaluation_requested.proto";
import "sentry_protos/billing/v1/services/events/v1/contract_rolled_over.proto";
import "sentry_protos/billing/v1/services/events/v1/one_off_invoice_updated.proto";
import "sentry_protos/billing/v1/services/events/v1/organization_over_usage.proto";
import "sentry_protos/billing/v1/services/events/v1/organization_package_changed.proto";
import "sentry_protos/billing/v1/services/events/v1/organization_payg_changed.proto";
Expand All @@ -25,6 +26,7 @@ message EventPayload {
sentry_protos.billing.v1.services.events.v1.ContractRolledOver contract_rolled_over = 5;
sentry_protos.billing.v1.services.events.v1.OrganizationPackageChanged organization_package_changed = 6;
sentry_protos.billing.v1.services.events.v1.BillingAlertEvaluationRequested billing_alert_evaluation_requested = 7;
sentry_protos.billing.v1.services.events.v1.OneOffInvoiceUpdated one_off_invoice_updated = 8;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
syntax = "proto3";

package sentry_protos.billing.v1.services.events.v1;

// Published when a one-off invoice changes state, so the service that
// requested it can grant, withhold or claw back what was purchased.
message OneOffInvoiceUpdated {
enum Outcome {
OUTCOME_UNSPECIFIED = 0;
OUTCOME_PAID = 1;
// Retries ran out or the invoice was closed. It can still be paid later,
// which publishes OUTCOME_PAID.
OUTCOME_CLOSED_UNPAID = 2;
OUTCOME_REFUNDED = 3;
}

uint64 invoice_id = 1;
string invoice_guid = 2;
string idempotency_key = 3;
Outcome outcome = 4;
// PAID: the invoice's amount_billed. REFUNDED: the amount of this refund,
// for the invoice as a whole rather than per line.
uint64 amount_cents = 5;
// The service that requested the invoice. A handler acts only on events
// carrying its own client_id; idempotency_key is unique within it.
string client_id = 6;
}
47 changes: 47 additions & 0 deletions rust/src/sentry_protos.billing.v1.services.contract.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,10 @@ pub struct InvoiceLineItem {
/// priced line items.
#[prost(string, optional, tag = "3")]
pub r#type: ::core::option::Option<::prost::alloc::string::String>,
/// Caller-defined identifier for what this line bills, set on one-off
/// invoice lines. Opaque to the platform.
#[prost(string, optional, tag = "4")]
pub external_id: ::core::option::Option<::prost::alloc::string::String>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Invoice {
Expand Down Expand Up @@ -595,6 +599,49 @@ pub struct Invoice {
/// false means the invoice is visible on receipts.
#[prost(bool, tag = "15")]
pub hide_from_customer_receipts: bool,
#[prost(enumeration = "InvoiceKind", tag = "16")]
pub kind: i32,
/// Caller-supplied key that makes one-off invoice creation safe to retry.
/// Unique per organization and client_id; unset on contract invoices.
#[prost(string, optional, tag = "17")]
pub idempotency_key: ::core::option::Option<::prost::alloc::string::String>,
/// Identifies the service that requested a one-off invoice, so it can
/// recognize its own invoices and map idempotency_key back to its own
/// records. Unset on contract invoices.
#[prost(string, optional, tag = "18")]
pub client_id: ::core::option::Option<::prost::alloc::string::String>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum InvoiceKind {
/// Invoices written before kinds existed; these are all contract invoices.
Unspecified = 0,
/// Created or rolled over alongside a contract.
Contract = 1,
/// Billed to an organization outside of any contract, charged immediately.
OneOff = 2,
}
impl InvoiceKind {
/// String value of the enum field names used in the ProtoBuf definition.
///
/// The values are not transformed in any way and thus are considered stable
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
pub fn as_str_name(&self) -> &'static str {
match self {
Self::Unspecified => "INVOICE_KIND_UNSPECIFIED",
Self::Contract => "INVOICE_KIND_CONTRACT",
Self::OneOff => "INVOICE_KIND_ONE_OFF",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
match value {
"INVOICE_KIND_UNSPECIFIED" => Some(Self::Unspecified),
"INVOICE_KIND_CONTRACT" => Some(Self::Contract),
"INVOICE_KIND_ONE_OFF" => Some(Self::OneOff),
_ => None,
}
}
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct OptionValue {
Expand Down
72 changes: 71 additions & 1 deletion rust/src/sentry_protos.billing.v1.services.events.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,74 @@ pub struct BillingAlertEvaluationRequested {}
/// Future: uint64 new_contract_id = 2;
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct ContractRolledOver {}
/// Published when a one-off invoice changes state, so the service that
/// requested it can grant, withhold or claw back what was purchased.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct OneOffInvoiceUpdated {
#[prost(uint64, tag = "1")]
pub invoice_id: u64,
#[prost(string, tag = "2")]
pub invoice_guid: ::prost::alloc::string::String,
#[prost(string, tag = "3")]
pub idempotency_key: ::prost::alloc::string::String,
#[prost(enumeration = "one_off_invoice_updated::Outcome", tag = "4")]
pub outcome: i32,
/// PAID: the invoice's amount_billed. REFUNDED: the amount of this refund,
/// for the invoice as a whole rather than per line.
#[prost(uint64, tag = "5")]
pub amount_cents: u64,
/// The service that requested the invoice. A handler acts only on events
/// carrying its own client_id; idempotency_key is unique within it.
#[prost(string, tag = "6")]
pub client_id: ::prost::alloc::string::String,
}
/// Nested message and enum types in `OneOffInvoiceUpdated`.
pub mod one_off_invoice_updated {
#[derive(
Clone,
Copy,
Debug,
PartialEq,
Eq,
Hash,
PartialOrd,
Ord,
::prost::Enumeration
)]
#[repr(i32)]
pub enum Outcome {
Unspecified = 0,
Paid = 1,
/// Retries ran out or the invoice was closed. It can still be paid later,
/// which publishes OUTCOME_PAID.
ClosedUnpaid = 2,
Refunded = 3,
}
impl Outcome {
/// String value of the enum field names used in the ProtoBuf definition.
///
/// The values are not transformed in any way and thus are considered stable
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
pub fn as_str_name(&self) -> &'static str {
match self {
Self::Unspecified => "OUTCOME_UNSPECIFIED",
Self::Paid => "OUTCOME_PAID",
Self::ClosedUnpaid => "OUTCOME_CLOSED_UNPAID",
Self::Refunded => "OUTCOME_REFUNDED",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
match value {
"OUTCOME_UNSPECIFIED" => Some(Self::Unspecified),
"OUTCOME_PAID" => Some(Self::Paid),
"OUTCOME_CLOSED_UNPAID" => Some(Self::ClosedUnpaid),
"OUTCOME_REFUNDED" => Some(Self::Refunded),
_ => None,
}
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct OrganizationOverUsage {}
/// Published when an organization's contract moves to a different package, e.g. a
Expand Down Expand Up @@ -33,7 +101,7 @@ pub struct EventMeta {
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct EventPayload {
#[prost(oneof = "event_payload::Payload", tags = "1, 2, 3, 4, 5, 6, 7")]
#[prost(oneof = "event_payload::Payload", tags = "1, 2, 3, 4, 5, 6, 7, 8")]
pub payload: ::core::option::Option<event_payload::Payload>,
}
/// Nested message and enum types in `EventPayload`.
Expand All @@ -54,6 +122,8 @@ pub mod event_payload {
OrganizationPackageChanged(super::OrganizationPackageChanged),
#[prost(message, tag = "7")]
BillingAlertEvaluationRequested(super::BillingAlertEvaluationRequested),
#[prost(message, tag = "8")]
OneOffInvoiceUpdated(super::OneOffInvoiceUpdated),
}
}
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
Expand Down
Loading