wyyerd/stripe-rs

How to CheckoutSession?

mikeumus opened this issue ยท 3 comments

I've been reading through the source trying to figure it out. Got stuck on the stripe::CheckoutSessionItem::id:

    let checkout_sesh = stripe::CheckoutSession {
        success_url: format!("{:?}/success.html?session_id={{CHECKOUT_SESSION_ID}}", domain),
        cancel_url: format!("{:?}/canceled.html", domain),
        payment_method_types: vec!["card".to_string()],
        mode: serde::__private::Some(stripe::CheckoutSessionMode::Subscription),
        line_items: vec![
            stripe::CheckoutSessionItem {
                // id: stripe::CheckoutSessionItemId { 0: 1234 },
                // id: None,
                // id: "val".into(),
                id: "val".to_string(),
                amount_total: None,
                amount_subtotal: None,
                description: "description".to_string(),
                taxes: None,
                // currency: "USD".to_string(),
                currency: stripe::Currency::USD,
                price: json.get("Price").unwrap(),
                quantity: Some(u64::from(1)),
            },
            // data: {
            //     "Price" = json.get("price").unwrap(),
            //     "Quantity": u64::from(1)
            // },
            // has_more: true,
            // total_count: serde::__private::Some(u64::from(1)),
            // url: "test_url".to_string(),

        ]
    };

I found this:

def_id!(CheckoutSessionItemId: String); // TODO: Figure out what prefix this id has

๐Ÿ‘† in the source typed as a String but trying to set a String as the id above gives:

expected struct `stripe::CheckoutSessionItemId`, found struct `std::string::String`

Any insight would be greatly appreciated.
Thank you ๐Ÿ™‡๐Ÿปโ€โ™‚๏ธ

Hi! Yes, it is a string but CheckoutSessionItemId uses the newtype pattern to provide type safety.

See here: https://docs.rs/stripe-rust/0.12.3/src/stripe/ids.rs.html#121

Luckily CheckoutSessionItemId implements FromStr (so does all the rest of the macro-derived string newtypes here) so you should be able to do the following:

CheckoutSessionItem {
    id: CheckoutSessionItemId::from_str("val"),
    ...
}

This is so we can provide errors when you provide an invalid ID for certain types, as some have required prefixes.

My problem with CheckoutSession is actually the id field. I'm creating it so how will I know ahead of time what the id will be?

	let client = stripe::Client::new(dotenv!("STRIPE_SECRET"));
	let price = Price::retrieve(&client, &PriceId::from_str(dotenv!("STRIPE_PRICE_ID"))?, &[]).await.unwrap();

	let mut line_items = List::default();
	line_items.data.push(CheckoutSessionItem {
		amount_total: None,
		amount_subtotal: None,
		currency: Currency::EUR,
		description: "Subscription".to_string(),
		id: CheckoutSessionItemId::from_str("yearly")?,
		price,
		quantity: Some(1),
		taxes: None,
	});

	let session = CheckoutSession {
		billing_address_collection: None,
		cancel_url: "/api/v1/payment/cancel".to_string(),
		client_reference_id: Some(user.id),
		customer: None,
		customer_email: Some(user_obj.email),
		display_items: None,
		id: None,
		line_items,
		livemode: false,
		locale: None,
		metadata: Metadata::new(),
		mode: Some(CheckoutSessionMode::Subscription),
		payment_intent: None,
		payment_method_types: vec!["card".to_string()],
		setup_intent: None,
		shipping: None,
		shipping_address_collection: None,
		submit_type: None,
		subscription: None,
		success_url: "/api/v1/payment/success".to_string(),
	};

It looks like the CheckoutSession is not completely implemented, you are missing the create function which normally takes a CreateCheckoutSession struct as input.

As an example, see how the PaymentIntent works: https://docs.rs/stripe-rust/0.12.3/stripe/struct.PaymentIntent.html#method.create

or the CheckoutSession in the async-stripe fork: https://docs.rs/async-stripe/latest/stripe/struct.CheckoutSession.html