Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
03c876b
Party here! (#60)
WWWcool Jun 4, 2025
404b870
Upgrades to dmt v2 (#59)
nanodirijabl Jun 9, 2025
d2f314b
Adds tag action
nanodirijabl Jun 9, 2025
b19de63
Removes obsolete testcases and fixtures; bumps deps (#62)
nanodirijabl Aug 4, 2025
92e192a
Bumps dmt protocol 2.2.12
nanodirijabl Aug 26, 2025
3a2c756
Bumps damsel v2.2.17
nanodirijabl Oct 29, 2025
baa1f32
Adds thrift handler for invoice-template creation w/ access token (#63)
nanodirijabl Dec 8, 2025
b9c92d5
BG-652: Get shop limits (#64)
WWWcool Jan 27, 2026
1c5f347
Adds OTEL middleware for swag's cowboy server (#65)
nanodirijabl Feb 9, 2026
35f4a11
FIX: Get shop limits (#66)
WWWcool Feb 10, 2026
b53c63b
BG-676: Add Customers
ndiezel0 Feb 18, 2026
6b6f433
Format
ndiezel0 Feb 18, 2026
999e18e
Fix
ndiezel0 Feb 19, 2026
74840f8
FIX: Allow in terminal and provider compute (#68)
WWWcool Feb 25, 2026
f9ce789
Review fix
ndiezel0 Feb 27, 2026
8bc2319
BG-800: Implement InspectUser (#69)
ndiezel0 Feb 27, 2026
85f9355
Format
ndiezel0 Mar 4, 2026
0f41cc0
Merge branch 'epic/party_here' into BG-676/customer
ndiezel0 Mar 4, 2026
813c69a
Updates
ndiezel0 Mar 18, 2026
a5a9176
Merge branch 'master' into BG-676/customer
ndiezel0 Mar 18, 2026
0542861
BG-834: Customers in new Payments
ndiezel0 Mar 23, 2026
f56f7fe
Latest changes
ndiezel0 Mar 30, 2026
97fda10
Merge branch 'master' into BG-676/customer
ndiezel0 Mar 30, 2026
3f2daa6
Use external_id in cubasty
ndiezel0 Apr 16, 2026
ea63050
Review fixes
ndiezel0 Apr 16, 2026
ec6af2a
Update damsel
ndiezel0 Apr 16, 2026
66f93aa
Update swag
ndiezel0 Apr 23, 2026
cbc703b
Format
ndiezel0 Apr 23, 2026
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ log
# make stuff
/.image.*
Makefile.env

.claude
CLAUDE.md
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
erlang 27.1.2
18 changes: 14 additions & 4 deletions apps/capi/src/capi_auth.erl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
-type consumer() :: client | merchant | provider.
-type token_spec() :: #{
party := binary(),
scope := {invoice | invoice_template, binary()},
scope := {invoice | invoice_template | customer, binary()},
shop => binary(),
lifetime => pos_integer() | unlimited,
metadata => token_keeper_client:metadata()
Expand Down Expand Up @@ -168,7 +168,8 @@ resolve_auth_scope(TokenSpec) ->
).

resolve_auth_method(#{scope := {invoice, _}}) -> ?CTX_V1_AUTHMETHOD_INVOICEACCESSTOKEN;
resolve_auth_method(#{scope := {invoice_template, _}}) -> ?CTX_V1_AUTHMETHOD_INVOICETEMPLATEACCESSTOKEN.
resolve_auth_method(#{scope := {invoice_template, _}}) -> ?CTX_V1_AUTHMETHOD_INVOICETEMPLATEACCESSTOKEN;
resolve_auth_method(#{scope := {customer, _}}) -> ?CTX_V1_AUTHMETHOD_CUSTOMERACCESSTOKEN.

resolve_auth_expiration(TokenSpec) ->
case get_token_lifetime(TokenSpec) of
Expand All @@ -185,18 +186,27 @@ get_token_lifetime(#{lifetime := LifeTime} = TokenSpec) when LifeTime =/= undefi
get_token_lifetime(#{scope := {invoice, _}}) ->
?DEFAULT_INVOICE_ACCESS_TOKEN_LIFETIME;
get_token_lifetime(#{scope := {invoice_template, _}}) ->
unlimited;
get_token_lifetime(#{scope := {customer, _}}) ->
unlimited.

verify_token_lifetime(#{scope := {invoice, _}}, LifeTime) when LifeTime =/= unlimited -> ok;
verify_token_lifetime(#{scope := {invoice_template, _}}, _LifeTime) -> ok.
verify_token_lifetime(#{scope := {invoice_template, _}}, _LifeTime) -> ok;
verify_token_lifetime(#{scope := {customer, _}}, _LifeTime) -> ok.

%%

create_metadata(TokenSpec) ->
PartyID = maps:get(party, TokenSpec),
Metadata0 = maps:get(metadata, TokenSpec, #{}),
Metadata1 = put_metadata(get_metadata_mapped_key(party_id), PartyID, Metadata0),
put_metadata(get_metadata_mapped_key(token_consumer), <<"client">>, Metadata1).
Metadata2 = put_metadata(get_metadata_mapped_key(token_consumer), <<"client">>, Metadata1),
maybe_put_customer_id(TokenSpec, Metadata2).

maybe_put_customer_id(#{scope := {customer, CustomerID}}, Metadata) ->
put_metadata(get_metadata_mapped_key(customer_id), CustomerID, Metadata);
maybe_put_customer_id(_TokenSpec, Metadata) ->
Metadata.

extract_auth_context(#{swagger_context := #{auth_context := AuthContext}}) ->
AuthContext.
Expand Down
40 changes: 38 additions & 2 deletions apps/capi/src/capi_bouncer_context.erl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
-include_lib("damsel/include/dmsl_payproc_thrift.hrl").
-include_lib("damsel/include/dmsl_domain_thrift.hrl").
-include_lib("damsel/include/dmsl_webhooker_thrift.hrl").
-include_lib("damsel/include/dmsl_customer_thrift.hrl").

-type fragment() :: bouncer_client:context_fragment().
-type acc() :: bouncer_context_helpers:context_fragment().
Expand All @@ -20,6 +21,7 @@
{operation, prototype_operation()}
| {payproc, prototype_payproc()}
| {webhooks, prototype_webhooks()}
| {cubasty, prototype_cubasty()}
].

-type prototype_operation() :: #{
Expand All @@ -30,7 +32,8 @@
payment => entity_id(),
refund => entity_id(),
invoice_template => entity_id(),
webhook => entity_id()
webhook => entity_id(),
customer => entity_id()
}.

-type prototype_payproc() :: #{
Expand All @@ -42,6 +45,10 @@
webhook => webhook_id() | webhook() | undefined
}.

-type prototype_cubasty() :: #{
customer => entity_id() | undefined
}.

-type invoice_id() :: dmsl_domain_thrift:'InvoiceID'().
-type invoice() :: dmsl_domain_thrift:'Invoice'().

Expand All @@ -57,6 +64,7 @@
-export_type([prototype_operation/0]).
-export_type([prototype_payproc/0]).
-export_type([prototype_webhooks/0]).
-export_type([prototype_cubasty/0]).

-export([new/0]).
-export([build/3]).
Expand Down Expand Up @@ -89,7 +97,8 @@ build(operation, #{id := OperationID} = Params, Acc, _WoodyCtx) ->
payment = maybe_entity(payment, Params),
refund = maybe_entity(refund, Params),
invoice_template = maybe_entity(invoice_template, Params),
webhook = maybe_entity(webhook, Params)
webhook = maybe_entity(webhook, Params),
customer = maybe_entity(customer, Params)
}
}
};
Expand Down Expand Up @@ -117,6 +126,16 @@ build(webhooks, #{} = Params, Acc, WoodyCtx) ->
fun(V) -> build_webhook_ctx(V, WoodyCtx) end
)
}
};
build(cubasty, #{} = Params, Acc, WoodyCtx) ->
Acc#ctx_v1_ContextFragment{
cubasty = #ctx_v1_ContextCustomerManagement{
customer = maybe_with(
customer,
Params,
fun(V) -> build_customer_ctx(V, WoodyCtx) end
)
}
}.

%%
Expand Down Expand Up @@ -196,6 +215,23 @@ build_webhook_filter({Type, Filter}) ->
build_webhook_filter_details(#webhooker_InvoiceEventFilter{shop_ref = #domain_ShopConfigRef{id = ShopID}}, Ctx) ->
Ctx#ctx_v1_WebhookFilter{shop = 'maybe'(ShopID, fun build_entity/1)}.

build_customer_ctx(ID, WoodyCtx) when is_binary(ID) ->
maybe_with_woody_result(
customer_management,
'Get',
{ID},
WoodyCtx,
fun build_customer_ctx/1
);
build_customer_ctx(CustomerState, _WoodyCtx) ->
build_customer_ctx(CustomerState).

build_customer_ctx(#customer_CustomerState{customer = Customer}) ->
#ctx_v1_Customer{
id = Customer#customer_Customer.id,
party = build_entity(Customer#customer_Customer.party_ref#domain_PartyConfigRef.id)
}.

%%

'maybe'(undefined, _Then) ->
Expand Down
24 changes: 24 additions & 0 deletions apps/capi/src/capi_feature_schemas.erl
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,13 @@
-define(postal_code, 71).
-define(date_of_birth, 72).
-define(document_id, 73).
-define(metadata, 74).

-export([payment/0]).
-export([invoice/0]).
-export([invoice_template/0]).
-export([refund/0]).
-export([customer/0]).

-spec payment() -> schema().
payment() ->
Expand Down Expand Up @@ -166,6 +168,28 @@ refund() ->
?allocation => {<<"allocation">>, {set, allocation_transaction()}}
}.

-spec customer() -> schema().
customer() ->
#{
?contact_info => {<<"contactInfo">>, contact_info_schema()},
?metadata => <<"metadata">>
}.

contact_info_schema() ->
#{
?email => <<"email">>,
?phone_number => <<"phoneNumber">>,
?first_name => <<"firstName">>,
?last_name => <<"lastName">>,
?country => <<"country">>,
?state => <<"state">>,
?city => <<"city">>,
?address => <<"address">>,
?postal_code => <<"postalCode">>,
?date_of_birth => <<"dateOfBirth">>,
?document_id => <<"documentId">>
}.

-spec payment_tool_schema() -> schema().
payment_tool_schema() ->
{union, <<"type">>, #{
Expand Down
2 changes: 2 additions & 0 deletions apps/capi/src/capi_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ get_handlers() ->
capi_handler_antifraud,
capi_handler_categories,
capi_handler_countries,
capi_handler_customers,
capi_handler_invoice_templates,
capi_handler_invoices,
capi_handler_parties,
Expand Down Expand Up @@ -309,6 +310,7 @@ set_context_meta(Context) ->
-spec set_request_meta(operation_id(), request_data()) -> ok.
set_request_meta(OperationID, Req) ->
InterestParams = [
'customerID',
'invoiceID',
'invoiceTemplateID',
'webhookID',
Expand Down
Loading
Loading