Skip to main content

src/livery_stripe_checkout.erl

-module(livery_stripe_checkout).
-moduledoc """
Stripe Checkout Sessions API.

`subscription_session/2` is the friendpaste flow: a hosted subscription
checkout for a single price, with success/cancel URLs and metadata.
""".

-export([create_session/2, retrieve_session/2, expire_session/2, subscription_session/2]).

-define(BASE, <<"/checkout/sessions">>).

-spec create_session(livery_client:client(), map() | list()) -> {ok, map()} | {error, term()}.
create_session(Client, Params) ->
    livery_stripe_client:do_request(Client, post, ?BASE, Params).

-spec retrieve_session(livery_client:client(), binary()) -> {ok, map()} | {error, term()}.
retrieve_session(Client, Id) ->
    livery_stripe_client:do_request(Client, get, sid(Id), none).

-spec expire_session(livery_client:client(), binary()) -> {ok, map()} | {error, term()}.
expire_session(Client, Id) ->
    livery_stripe_client:do_request(Client, post, <<(sid(Id))/binary, "/expire">>, []).

-doc """
Create a subscription-mode checkout session for a single price, mirroring
friendpaste's billing flow.

`Params` requires `customer`, `price`, `success_url`, `cancel_url`, and
accepts optional `quantity` (default 1) and `metadata`.
""".
-spec subscription_session(livery_client:client(), map()) -> {ok, map()} | {error, term()}.
subscription_session(Client, Params) ->
    #{
        customer := Customer,
        price := Price,
        success_url := SuccessUrl,
        cancel_url := CancelUrl
    } = Params,
    LineItem = #{<<"price">> => Price, <<"quantity">> => maps:get(quantity, Params, 1)},
    Body =
        [
            {<<"mode">>, <<"subscription">>},
            {<<"customer">>, Customer},
            {<<"line_items">>, [LineItem]},
            {<<"success_url">>, SuccessUrl},
            {<<"cancel_url">>, CancelUrl}
        ] ++ metadata(maps:get(metadata, Params, #{})),
    create_session(Client, Body).

metadata(M) when is_map(M), map_size(M) =:= 0 -> [];
metadata(M) -> [{<<"metadata">>, M}].

sid(Id) ->
    <<?BASE/binary, "/", Id/binary>>.