Skip to content

Commit

Permalink
feat: handle currency_options
Browse files Browse the repository at this point in the history
Currency_options field is represented by an optional HashMap<String, T>, where the String is the currency code in ISO 4217 format.

This affects the following resources:
- `CheckoutSession`: When defining the shipping rate fixed amount, there is the option of setting specific amounts per currency. See: https://stripe.com/docs/api/checkout/sessions/create#create_checkout_session-shipping_options-shipping_rate_data-fixed_amount-currency_options
- `Coupon`: Can have different amounts for different currencies. Which means that it can contain it, be created with it or be updated to have it. See: https://stripe.com/docs/api/coupons/object#coupon_object-currency_options
- `Invoice`: When defining shipping rate fixed amount, there is the option of setting specific amounts per currency. See: https://stripe.com/docs/api/invoices/create#create_invoice-shipping_cost-shipping_rate_data-fixed_amount-currency_options
- `Price`: A price can have different amounts available on different currencies. Which means that it can contain it, be created with it or be updated to have it. See: https://stripe.com/docs/api/invoices/create#create_invoice-shipping_cost-shipping_rate_data-fixed_amount-currency_options
- `Product`: When creating a product, it can be defined currency options of the nested prices (as defined above on `Price`). See: https://stripe.com/docs/api/products/create#create_product-default_price_data-currency_options
- `PromotionCode`: Promotion codes can have restrictions based on defined currencies. See: https://stripe.com/docs/api/promotion_codes/object#promotion_code_object-restrictions-currency_options
- `ShippingRate`: As seen on `CheckoutSession` and `Invoice`, a shipping rate can be defined per specific currency. See: https://stripe.com/docs/api/shipping_rates/object#shipping_rate_object-fixed_amount-currency_options
  • Loading branch information
augustoccesar committed May 25, 2023
1 parent b3732b1 commit 1bb8165
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 21 deletions.
6 changes: 6 additions & 0 deletions openapi/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1276,6 +1276,12 @@ pub fn gen_field_rust_type<T: Borrow<Schema>>(
return ty;
}

// currency_options field is represented by an optional HashMap<String, T>, where the String is the currency code in ISO 4217 format.
if field_name == "currency_options" {
state.use_params.insert("Map");
return format!("Option<Map<{}>>", ty);
}

let optional = !required || is_nullable;
let should_box = ty.as_str() == "ApiErrors";

Expand Down
1 change: 1 addition & 0 deletions src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ where
}
}

pub type Map<T> = HashMap<String, T>;
pub type Metadata = HashMap<String, String>;
pub type Timestamp = i64;

Expand Down
4 changes: 2 additions & 2 deletions src/resources/generated/checkout_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};

use crate::client::{Client, Response};
use crate::ids::{CheckoutSessionId, CustomerId, PaymentIntentId, PaymentLinkId, SubscriptionId};
use crate::params::{Expand, Expandable, List, Metadata, Object, Paginable, Timestamp};
use crate::params::{Expand, Expandable, List, Map, Metadata, Object, Paginable, Timestamp};
use crate::resources::{
Address, CheckoutSessionItem, Currency, Customer, Discount, Invoice,
InvoiceSettingRenderingOptions, LinkedAccountOptionsUsBankAccount, PaymentIntent, PaymentLink,
Expand Down Expand Up @@ -2728,7 +2728,7 @@ pub struct CreateCheckoutSessionShippingOptionsShippingRateDataFixedAmount {
/// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
#[serde(skip_serializing_if = "Option::is_none")]
pub currency_options:
Option<CreateCheckoutSessionShippingOptionsShippingRateDataFixedAmountCurrencyOptions>,
Option<Map<CreateCheckoutSessionShippingOptionsShippingRateDataFixedAmountCurrencyOptions>>,
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
Expand Down
10 changes: 6 additions & 4 deletions src/resources/generated/coupon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use serde::{Deserialize, Serialize};

use crate::client::{Client, Response};
use crate::ids::CouponId;
use crate::params::{Deleted, Expand, List, Metadata, Object, Paginable, RangeQuery, Timestamp};
use crate::params::{
Deleted, Expand, List, Map, Metadata, Object, Paginable, RangeQuery, Timestamp,
};
use crate::resources::Currency;

/// The resource representing a Stripe "Coupon".
Expand Down Expand Up @@ -38,7 +40,7 @@ pub struct Coupon {
///
/// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
#[serde(skip_serializing_if = "Option::is_none")]
pub currency_options: Option<CouponCurrencyOption>,
pub currency_options: Option<Map<CouponCurrencyOption>>,

// Always true for a deleted object
#[serde(default)]
Expand Down Expand Up @@ -170,7 +172,7 @@ pub struct CreateCoupon<'a> {
///
/// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
#[serde(skip_serializing_if = "Option::is_none")]
pub currency_options: Option<CreateCouponCurrencyOptions>,
pub currency_options: Option<Map<CreateCouponCurrencyOptions>>,

/// Specifies how long the discount will be in effect if used on a subscription.
///
Expand Down Expand Up @@ -301,7 +303,7 @@ pub struct UpdateCoupon<'a> {
///
/// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
#[serde(skip_serializing_if = "Option::is_none")]
pub currency_options: Option<UpdateCouponCurrencyOptions>,
pub currency_options: Option<Map<UpdateCouponCurrencyOptions>>,

/// Specifies which fields in the response should be expanded.
#[serde(skip_serializing_if = "Expand::is_empty")]
Expand Down
4 changes: 2 additions & 2 deletions src/resources/generated/invoice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
use crate::client::{Client, Response};
use crate::ids::{CustomerId, InvoiceId, SubscriptionId};
use crate::params::{
Deleted, Expand, Expandable, List, Metadata, Object, Paginable, RangeQuery, Timestamp,
Deleted, Expand, Expandable, List, Map, Metadata, Object, Paginable, RangeQuery, Timestamp,
};
use crate::resources::{
Account, Address, ApiErrors, Application, Charge, Currency, Customer, Discount,
Expand Down Expand Up @@ -1244,7 +1244,7 @@ pub struct CreateInvoiceShippingCostShippingRateDataFixedAmount {
/// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
#[serde(skip_serializing_if = "Option::is_none")]
pub currency_options:
Option<CreateInvoiceShippingCostShippingRateDataFixedAmountCurrencyOptions>,
Option<Map<CreateInvoiceShippingCostShippingRateDataFixedAmountCurrencyOptions>>,
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
Expand Down
8 changes: 4 additions & 4 deletions src/resources/generated/price.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
use crate::client::{Client, Response};
use crate::ids::PriceId;
use crate::params::{
Expand, Expandable, IdOrCreate, List, Metadata, Object, Paginable, RangeQuery, Timestamp,
Expand, Expandable, IdOrCreate, List, Map, Metadata, Object, Paginable, RangeQuery, Timestamp,
};
use crate::resources::{CreateProduct, Currency, CustomUnitAmount, Product, UpTo};

Expand Down Expand Up @@ -47,7 +47,7 @@ pub struct Price {
///
/// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
#[serde(skip_serializing_if = "Option::is_none")]
pub currency_options: Option<CurrencyOption>,
pub currency_options: Option<Map<CurrencyOption>>,

/// When set, provides configuration for the amount to be adjusted by the customer during Checkout Sessions and Payment Links.
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down Expand Up @@ -280,7 +280,7 @@ pub struct CreatePrice<'a> {
///
/// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
#[serde(skip_serializing_if = "Option::is_none")]
pub currency_options: Option<CreatePriceCurrencyOptions>,
pub currency_options: Option<Map<CreatePriceCurrencyOptions>>,

/// When set, provides configuration for the amount to be adjusted by the customer during Checkout Sessions and Payment Links.
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down Expand Up @@ -485,7 +485,7 @@ pub struct UpdatePrice<'a> {
///
/// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
#[serde(skip_serializing_if = "Option::is_none")]
pub currency_options: Option<UpdatePriceCurrencyOptions>,
pub currency_options: Option<Map<Option<Map<UpdatePriceCurrencyOptions>>>>,

/// Specifies which fields in the response should be expanded.
#[serde(skip_serializing_if = "Expand::is_empty")]
Expand Down
4 changes: 2 additions & 2 deletions src/resources/generated/product.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
use crate::client::{Client, Response};
use crate::ids::{ProductId, TaxCodeId};
use crate::params::{
Deleted, Expand, Expandable, List, Metadata, Object, Paginable, RangeQuery, Timestamp,
Deleted, Expand, Expandable, List, Map, Metadata, Object, Paginable, RangeQuery, Timestamp,
};
use crate::resources::{Currency, Price, TaxCode, UpTo};

Expand Down Expand Up @@ -509,7 +509,7 @@ pub struct CreateProductDefaultPriceData {
///
/// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
#[serde(skip_serializing_if = "Option::is_none")]
pub currency_options: Option<CreateProductDefaultPriceDataCurrencyOptions>,
pub currency_options: Option<Map<CreateProductDefaultPriceDataCurrencyOptions>>,

/// The recurring components of a price such as `interval` and `interval_count`.
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down
8 changes: 5 additions & 3 deletions src/resources/generated/promotion_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use serde::{Deserialize, Serialize};

use crate::client::{Client, Response};
use crate::ids::{CouponId, CustomerId, PromotionCodeId};
use crate::params::{Expand, Expandable, List, Metadata, Object, Paginable, RangeQuery, Timestamp};
use crate::params::{
Expand, Expandable, List, Map, Metadata, Object, Paginable, RangeQuery, Timestamp,
};
use crate::resources::{Coupon, Currency, Customer};

/// The resource representing a Stripe "PromotionCode".
Expand Down Expand Up @@ -102,7 +104,7 @@ pub struct PromotionCodesResourceRestrictions {
///
/// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
#[serde(skip_serializing_if = "Option::is_none")]
pub currency_options: Option<PromotionCodeCurrencyOption>,
pub currency_options: Option<Map<PromotionCodeCurrencyOption>>,

/// A Boolean indicating if the Promotion Code should only be redeemed for Customers without any successful payments or invoices.
pub first_time_transaction: bool,
Expand Down Expand Up @@ -234,7 +236,7 @@ pub struct UpdatePromotionCodeRestrictions {
///
/// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
#[serde(skip_serializing_if = "Option::is_none")]
pub currency_options: Option<UpdatePromotionCodeRestrictionsCurrencyOptions>,
pub currency_options: Option<Map<UpdatePromotionCodeRestrictionsCurrencyOptions>>,
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
Expand Down
10 changes: 6 additions & 4 deletions src/resources/generated/shipping_rate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use serde::{Deserialize, Serialize};

use crate::client::{Client, Response};
use crate::ids::{ShippingRateId, TaxCodeId};
use crate::params::{Expand, Expandable, List, Metadata, Object, Paginable, RangeQuery, Timestamp};
use crate::params::{
Expand, Expandable, List, Map, Metadata, Object, Paginable, RangeQuery, Timestamp,
};
use crate::resources::{Currency, TaxCode};

/// The resource representing a Stripe "ShippingRate".
Expand Down Expand Up @@ -141,7 +143,7 @@ pub struct ShippingRateFixedAmount {
///
/// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
#[serde(skip_serializing_if = "Option::is_none")]
pub currency_options: Option<ShippingRateCurrencyOption>,
pub currency_options: Option<Map<ShippingRateCurrencyOption>>,
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
Expand Down Expand Up @@ -358,7 +360,7 @@ pub struct CreateShippingRateFixedAmount {
///
/// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
#[serde(skip_serializing_if = "Option::is_none")]
pub currency_options: Option<CreateShippingRateFixedAmountCurrencyOptions>,
pub currency_options: Option<Map<CreateShippingRateFixedAmountCurrencyOptions>>,
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
Expand All @@ -367,7 +369,7 @@ pub struct UpdateShippingRateFixedAmount {
///
/// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
#[serde(skip_serializing_if = "Option::is_none")]
pub currency_options: Option<UpdateShippingRateFixedAmountCurrencyOptions>,
pub currency_options: Option<Map<UpdateShippingRateFixedAmountCurrencyOptions>>,
}

#[derive(Clone, Debug, Default, Deserialize, Serialize)]
Expand Down
70 changes: 70 additions & 0 deletions tests/price.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
mod mock;

// Using fixture for this test because the stripe-mock server does not (currently [2023-05-25]) support the `currency_options` field.
// See: https://github.com/stripe/stripe-mock/issues/420
#[test]
#[cfg(feature = "blocking")]
fn deserialize_currency_options() {
use stripe::{CurrencyOptionTaxBehavior, Price};

let fixture = r#"
{
"id": "price_1234",
"object": "price",
"active": true,
"billing_scheme": "per_unit",
"created": 1651739124,
"currency": "usd",
"currency_options": {
"eur": {
"custom_unit_amount": null,
"tax_behavior": "exclusive",
"unit_amount": 14388,
"unit_amount_decimal": "14388"
},
"usd": {
"custom_unit_amount": null,
"tax_behavior": "exclusive",
"unit_amount": 14388,
"unit_amount_decimal": "14388"
}
},
"custom_unit_amount": null,
"livemode": false,
"lookup_key": "lookup_key_1234",
"metadata": {},
"nickname": null,
"product": "prod_1234",
"recurring": {
"aggregate_usage": null,
"interval": "year",
"interval_count": 1,
"trial_period_days": null,
"usage_type": "licensed"
},
"tax_behavior": "exclusive",
"tiers_mode": null,
"transform_quantity": null,
"type": "recurring",
"unit_amount": 14388,
"unit_amount_decimal": "14388"
}
"#;

let result: Result<Price, serde_json::Error> = serde_json::from_str(fixture);
assert!(result.is_ok());

let price = result.unwrap();
assert!(&price.currency_options.is_some());

let currency_options = price.currency_options.unwrap();
let mut currency_options_keys = currency_options.keys().collect::<Vec<&String>>();
currency_options_keys.sort();
assert_eq!(vec!("eur", "usd"), currency_options_keys);

let usd_option = currency_options.get("usd").unwrap();
assert!(usd_option.custom_unit_amount.is_none());
assert_eq!(Some(14388), usd_option.unit_amount);
assert_eq!(Some(CurrencyOptionTaxBehavior::Exclusive), usd_option.tax_behavior);
assert_eq!(Some("14388".to_string()), usd_option.unit_amount_decimal);
}

0 comments on commit 1bb8165

Please sign in to comment.