0
votes

I am trying to calculate proration cost in Stripe using Elixir. I am using Stripity_Stripe library https://github.com/code-corps/stripity_stripe/tree/2.0-alpha

Here is what I did.

  1. Get a current time as unix time
proration_date = DateTime.to_unix(DateTime.utc_now)
  1. Get an upcoming invoice using Stripe.Invoice
params = %{customer: customer_id,
           subscription: subscription_id,
           subscription_items: [%{plan: plan_id}],
           subscription_proration_date: proration_date}

upcoming_invoice = Invoice.upcoming(params, opts)

I substitute customer_id to customer's id and subscription_id to customer's subscription_id and plan_id to new plan_id(that wants to make change) and subscription_proration_date as proration_date

it returns as

{:ok,
 %Stripe.Invoice{
   amount_due: 17226,
   application_fee: nil,
   attempt_count: 0,
   attempted: false,
   charge: nil,
   closed: false,
   currency: "usd",
   customer: "cus_CxY2gOrcBX568N",
   date: 1530382817,
   description: nil,
   discount: nil,
   ending_balance: nil,
   forgiven: false,
   id: nil,
   lines: %Stripe.List{
     data: [
       %{
         amount: 5235,
         currency: "usd",
         description: "Remaining time on Gold after 04 Jun 2018",
         discountable: false,
         id: "ii_1CZJOQE0U7CBdOnaJ2JiTU3p",
         invoice_item: "ii_1CZJOQE0U7CBdOnaJ2JiTU3p",
         livemode: false,
         metadata: %{},
         object: "line_item",
         period: %{end: 1530382817, start: 1528121306},
         plan: %Stripe.Plan{
           amount: 6000,
           created: 1527787728,
           currency: "usd",
           id: "plan_CxqGQzrlZKzsyX",
           interval: "month",
           interval_count: 1,
           livemode: false,
           metadata: %{},
           name: "Gold",
           object: "plan",
           statement_descriptor: "Gold",
           trial_period_days: nil
         },
         proration: true,
         quantity: 1,
         subscription: "sub_Cxr5eVusfDmwpD",
         subscription_item: "si_CzHykruREBJmer",
         type: "invoiceitem"
       },
       %{
         amount: -1991,
         currency: "usd",
         description: "Unused time on Bronze after 31 May 2018",
         discountable: false,
         id: "ii_1CXyMGE0U7CBdOna7pMyz65c",
         invoice_item: "ii_1CXyMGE0U7CBdOna7pMyz65c",
         livemode: false,
         metadata: %{},
         object: "line_item",
         period: %{end: 1530382817, start: 1527802256},
         plan: %Stripe.Plan{
           amount: 2000,
           created: 1527789541,
           currency: "usd",
           id: "plan_CxqkbcqfX4hDB8",
           interval: "month",
           interval_count: 1,
           livemode: false,
           metadata: %{},
           name: "Bronze",
           object: "plan",
           statement_descriptor: nil,
           trial_period_days: nil
         },
         proration: true,
         quantity: 1,
         subscription: "sub_Cxr5eVusfDmwpD",
         subscription_item: "si_Cxr5FLLMsPXBhq",
         type: "invoiceitem"
       },
       %{
         amount: 3982,
         currency: "usd",
         description: "Remaining time on Silver after 31 May 2018",
         discountable: false,
         id: "ii_1CXyMGE0U7CBdOnazohKmlP6",
         invoice_item: "ii_1CXyMGE0U7CBdOnazohKmlP6",
         livemode: false,
         metadata: %{},
         object: "line_item",
         period: %{end: 1530382817, start: 1527802256},
         plan: %Stripe.Plan{
           amount: 4000,
           created: 1527787680,
           currency: "usd",
           id: "plan_CxqFiVIY2FqTL3",
           interval: "month",
           interval_count: 1,
           livemode: false,
           metadata: %{},
           name: "Silver",
           object: "plan",
           statement_descriptor: "Silver",
           trial_period_days: nil
         },
         proration: true,
         quantity: 1,
         subscription: "sub_Cxr5eVusfDmwpD",
         subscription_item: "si_Cxr5FLLMsPXBhq",
         type: "invoiceitem"
       },
       %{
         amount: 4000,
         currency: "usd",
         description: nil,
         discountable: true,
         id: "sub_Cxr5eVusfDmwpD",
         livemode: false, 
         metadata: %{},
         object: "line_item",
         period: %{end: 1533061217, start: 1530382817},
         plan: %Stripe.Plan{
           amount: 4000,
           created: 1527787680,
           currency: "usd",
           id: "plan_CxqFiVIY2FqTL3",
           interval: "month",
           interval_count: 1,
           livemode: false,
           metadata: %{},
           name: "Silver",
           object: "plan", 
           statement_descriptor: "Silver",
           trial_period_days: nil
         },
         proration: false,
         quantity: 1,
         subscription: nil,
         subscription_item: "si_Cxr5FLLMsPXBhq",
         type: "subscription"
       },
       %{
         amount: 6000,
         currency: "usd",
         description: nil,
         discountable: true,
         id: "sub_Cxr5eVusfDmwpD",
         livemode: false,
         metadata: %{},
         object: "line_item",
         period: %{end: 1533061217, start: 1530382817},
         plan: %Stripe.Plan{
           amount: 6000,
           created: 1527787728,
           currency: "usd",
           id: "plan_CxqGQzrlZKzsyX",
           interval: "month",
           interval_count: 1,
           livemode: false,
           metadata: %{},
           name: "Gold",
           object: "plan",
           statement_descriptor: "Gold",
           trial_period_days: nil
         },
         proration: false,
         quantity: 1,
         subscription: nil,
         subscription_item: "si_CzHykruREBJmer",
         type: "subscription"
       }
     ],
     has_more: false,
     object: "list",
     total_count: 5,
     url: "/v1/invoices/upcoming/lines?customer=cus_CxY2gOrcBX568N&subscription=sub_Cxr5eVusfDmwpD&subscription_proration_date=1528121306"
   },
   livemode: false, 
   metadata: %{},
   next_payment_attempt: 1530386417,
   object: "invoice",
   paid: false,
   period_end: 1530382817,
   period_start: 1527790817,
   receipt_number: nil,
   starting_balance: 0,
   statement_descriptor: nil,
   subscription: "sub_Cxr5eVusfDmwpD",
   subscription_proration_date: 1528121306,
   subtotal: 17226,
   tax: nil,
   tax_percent: nil,
   total: 17226,
   webhooks_delivered_at: nil
 }}
  1. So I did a pattern match to get data items as this(https://stripe.com/docs/billing/subscriptions/prorations)

{:ok, %Stripe.Invoice{lines: %Stripe.List{data: data}}} = upcoming_invoice

  1. Then I tried this

    data |> Enum.find(& &1.period.start == proration_date)

  2. it returns this

%{
  amount: 5235,
  currency: "usd",
  description: "Remaining time on Gold after 04 Jun 2018",
  discountable: false,
  id: "ii_1CZJPIE0U7CBdOna36eKJQfg",
  invoice_item: "ii_1CZJPIE0U7CBdOna36eKJQfg",
  livemode: false,
  metadata: %{},
  object: "line_item",
  period: %{end: 1530382817, start: 1528121306},
  plan: %Stripe.Plan{
    amount: 6000,
    created: 1527787728,
    currency: "usd",
    id: "plan_CxqGQzrlZKzsyX",
    interval: "month",
    interval_count: 1,
    livemode: false,
    metadata: %{},
    name: "Gold",
    object: "plan",
    statement_descriptor: "Gold",
    trial_period_days: nil
  },
  proration: true,
  quantity: 1,
  subscription: "sub_Cxr5eVusfDmwpD",
  subscription_item: "si_CzHzbTUPBrfqPA",
  type: "invoiceitem"
}

Then I don't know what to do next. In stripe documents using python, do it like this.

current_prorations = [ii for ii in invoice.lines.data if ii.period.start == proration_date]
cost = sum([p.amount for p in current_prorations])

but my code return only 1 result and I upgraded plan to check if my code return correct cost, but it was not correct.

What am I missing?

1
What if you change Enum.find to Enum.filter? I think you want all the elements which satisfy that criteria? - Dogbert
Thanks, It will work better, but my question is, how to properly calculate the proration cost. - Tae

1 Answers

0
votes

The most straightforward translation of your two lines of Python code would be this:

current_prorations = for ii <- invoice.lines.data, ii.period.start == proration_date, do: ii
cost = for(p <- current_prorations, do: p.amount) |> Enum.sum()