Current section

20 Versions

Jump to

Compare versions

13 files changed
+385 additions
-28 deletions
  @@ -1,3 +1,25 @@
1 + ## v0.12.0 2021-09-02
2 +
3 + ### Changed
4 +
5 + - Bumped the minium Elixir version from `1.7` to `1.9` (it had been a while!)
6 +
7 + ### Added
8 +
9 + - [Braintree.Webhook] A new module that provides convenience methods for parsing
10 + Braintree webhook payloads.
11 +
12 + - [Braintree] Wrap HTTP calls in telemetry events for instrumentation. All
13 + requests are wrapped in a telemetry events, which emits standard span events:
14 +
15 + `[:braintree, :request, :start | :stop | :exception | :error]`
16 +
17 + - [Braintree.Customer] Support ApplePay and AndroidPay
18 +
19 + ### Fixed
20 +
21 + - Fix atomizing nested maps with mixed keys.
22 +
1 23 ## v0.11.0 2020-05-11
2 24
3 25 * [Braintree] Allow configuration of sandbox endpoint for testing
  @@ -117,6 +117,43 @@ search_params = %{
117 117
118 118 [doc]: https://developers.braintreepayments.com/
119 119
120 +
121 + ### Telemetry
122 +
123 + If the `telemetry` application is running, the library will emit telemetry events.
124 +
125 + Immediately before the HTTP request is fired, a start event will be fired with the following shape:
126 +
127 + ```
128 + event name: [:braintree, :request, :start]
129 + measurements: %{system_time: System.system_time()}
130 + meta data: %{method: method, path: path}
131 + ```
132 +
133 + Once the HTTP call completes, a stop event will be fired with the following shape:
134 +
135 + ```
136 + event name: [:braintree, :request, :stop]
137 + measurements: %{duration: duration}
138 + meta data: %{method: method, path: path, http_status: status}
139 + ```
140 +
141 + If Hackney returns an error, an error event will be fired with the following shape:
142 +
143 + ```
144 + event name: [:braintree, :request, :error]
145 + measurements: %{duration: duration}
146 + meta data: %{method: method, path: path, error: error_reason}
147 + ```
148 +
149 + If an exception is raised during the Hackney call, an exception event will be fired with the following shape:
150 +
151 + ```
152 + event name: [:braintree, :request, :exception]
153 + measurements: %{duration: duration}
154 + meta data: %{method: method, path: path, kind: error_type, reason: error_message, stacktrace: stacktrace}
155 + ```
156 +
120 157 ## Testing
121 158
122 159 You'll need a Braintree sandbox account to run the integration tests. Also, be
  @@ -148,9 +185,11 @@ testing][plp].
148 185 You can optionally configure the sandbox endpoint url to point towards a local url and
149 186 port for testing which does not need to call out to the Braintree sandbox API.
150 187 For example, in your `config.exs`
151 - ```
188 +
189 + ```elixir
152 190 config :braintree, :sandbox_endpoint, "localhost:4001"
153 191 ```
192 +
154 193 In conjuction with a libary such as [`Bypass`](https://github.com/PSPDFKit-labs/bypass)
155 194 you can use this config to define test-specific returns from `Braintree` calls without
156 195 hitting the Braintree sandbox API.
  @@ -1,19 +1,22 @@
1 1 {<<"app">>,<<"braintree">>}.
2 2 {<<"build_tools">>,[<<"mix">>]}.
3 3 {<<"description">>,<<"Native Braintree client library for Elixir">>}.
4 - {<<"elixir">>,<<"~> 1.5">>}.
4 + {<<"elixir">>,<<"~> 1.9">>}.
5 5 {<<"files">>,
6 - [<<"lib">>,<<"lib/transaction.ex">>,<<"lib/credit_card_verification.ex">>,
7 - <<"lib/paypal_account.ex">>,<<"lib/construction.ex">>,<<"lib/util.ex">>,
8 - <<"lib/braintree.ex">>,<<"lib/settlement_batch_summary.ex">>,
6 + [<<"lib">>,<<"lib/webhook">>,<<"lib/webhook/digest.ex">>,
7 + <<"lib/webhook/validation.ex">>,<<"lib/transaction.ex">>,
8 + <<"lib/credit_card_verification.ex">>,<<"lib/paypal_account.ex">>,
9 + <<"lib/construction.ex">>,<<"lib/util.ex">>,<<"lib/braintree.ex">>,
10 + <<"lib/apple_pay_card.ex">>,<<"lib/settlement_batch_summary.ex">>,
9 11 <<"lib/address.ex">>,<<"lib/plan.ex">>,<<"lib/payment_method.ex">>,
10 - <<"lib/add_on.ex">>,<<"lib/credit_card.ex">>,<<"lib/subscription.ex">>,
11 - <<"lib/xml">>,<<"lib/xml/encoder.ex">>,<<"lib/xml/decoder.ex">>,
12 - <<"lib/xml/entity.ex">>,<<"lib/error_response.ex">>,<<"lib/customer.ex">>,
13 - <<"lib/testing">>,<<"lib/testing/test_transaction.ex">>,
14 - <<"lib/testing/nonces.ex">>,<<"lib/testing/credit_card_numbers.ex">>,
15 - <<"lib/transaction_line_item.ex">>,<<"lib/payment_method_nonce.ex">>,
16 - <<"lib/http.ex">>,<<"lib/client_token.ex">>,<<"lib/search.ex">>,
12 + <<"lib/add_on.ex">>,<<"lib/credit_card.ex">>,<<"lib/webhook.ex">>,
13 + <<"lib/subscription.ex">>,<<"lib/xml">>,<<"lib/xml/encoder.ex">>,
14 + <<"lib/xml/decoder.ex">>,<<"lib/xml/entity.ex">>,
15 + <<"lib/error_response.ex">>,<<"lib/customer.ex">>,<<"lib/testing">>,
16 + <<"lib/testing/test_transaction.ex">>,<<"lib/testing/nonces.ex">>,
17 + <<"lib/testing/credit_card_numbers.ex">>,<<"lib/transaction_line_item.ex">>,
18 + <<"lib/payment_method_nonce.ex">>,<<"lib/http.ex">>,
19 + <<"lib/android_pay_card.ex">>,<<"lib/client_token.ex">>,<<"lib/search.ex">>,
17 20 <<"lib/discount.ex">>,<<"lib/merchant">>,<<"lib/merchant/funding.ex">>,
18 21 <<"lib/merchant/account.ex">>,<<"lib/merchant/business.ex">>,
19 22 <<"lib/merchant/individual.ex">>,<<"priv">>,<<"priv/entities.txt">>,
  @@ -28,5 +31,15 @@
28 31 {<<"name">>,<<"hackney">>},
29 32 {<<"optional">>,false},
30 33 {<<"repository">>,<<"hexpm">>},
31 - {<<"requirement">>,<<"~> 1.15">>}]]}.
32 - {<<"version">>,<<"0.11.0">>}.
34 + {<<"requirement">>,<<"~> 1.15">>}],
35 + [{<<"app">>,<<"plug">>},
36 + {<<"name">>,<<"plug">>},
37 + {<<"optional">>,false},
38 + {<<"repository">>,<<"hexpm">>},
39 + {<<"requirement">>,<<"~> 1.12">>}],
40 + [{<<"app">>,<<"telemetry">>},
41 + {<<"name">>,<<"telemetry">>},
42 + {<<"optional">>,false},
43 + {<<"repository">>,<<"hexpm">>},
44 + {<<"requirement">>,<<"~> 1.0">>}]]}.
45 + {<<"version">>,<<"0.12.0">>}.
  @@ -0,0 +1,49 @@
1 + defmodule Braintree.AndroidPayCard do
2 + @moduledoc """
3 + AndroidPayCard structs are not created directly, but are built within
4 + responses from other endpoints, such as `Braintree.Customer`.
5 +
6 + For additional reference see:
7 + https://developers.braintreepayments.com/reference/response/android-pay-card/ruby
8 + """
9 + use Braintree.Construction
10 +
11 + @type t :: %__MODULE__{
12 + bin: String.t(),
13 + created_at: String.t(),
14 + customer_id: String.t(),
15 + default: boolean,
16 + expiration_month: String.t(),
17 + expiration_year: String.t(),
18 + google_transaction_id: String.t(),
19 + image_url: String.t(),
20 + is_network_tokenized: boolean,
21 + source_card_last_4: String.t(),
22 + source_card_type: String.t(),
23 + source_description: String.t(),
24 + subscriptions: [any],
25 + token: String.t(),
26 + updated_at: String.t(),
27 + virtual_card_last_4: String.t(),
28 + virtual_card_type: String.t()
29 + }
30 +
31 + defstruct bin: nil,
32 + billing_address: nil,
33 + created_at: nil,
34 + customer_id: nil,
35 + default: false,
36 + expiration_month: nil,
37 + expiration_year: nil,
38 + google_transaction_id: nil,
39 + image_url: nil,
40 + is_network_tokenized: false,
41 + source_card_last_4: nil,
42 + source_card_type: nil,
43 + source_description: nil,
44 + subscriptions: [],
45 + token: nil,
46 + updated_at: nil,
47 + virtual_card_last_4: nil,
48 + virtual_card_type: nil
49 + end
  @@ -0,0 +1,47 @@
1 + defmodule Braintree.ApplePayCard do
2 + @moduledoc """
3 + ApplePayCard structs are not created directly, but are built within
4 + responsees from other endpoints, such as `Braintree.Customer`.
5 + """
6 +
7 + use Braintree.Construction
8 + alias Braintree.Address
9 +
10 + @type t :: %__MODULE__{
11 + billing_address: Address.t(),
12 + bin: String.t(),
13 + card_type: String.t(),
14 + cardholder_name: String.t(),
15 + created_at: String.t(),
16 + customer_id: String.t(),
17 + default: String.t(),
18 + expiration_month: String.t(),
19 + expiration_year: String.t(),
20 + expired: String.t(),
21 + image_url: String.t(),
22 + last_4: String.t(),
23 + payment_instrument_name: String.t(),
24 + source_description: String.t(),
25 + subscriptions: [any],
26 + token: String.t(),
27 + updated_at: String.t()
28 + }
29 +
30 + defstruct billing_address: nil,
31 + bin: nil,
32 + card_type: nil,
33 + cardholder_name: nil,
34 + created_at: nil,
35 + customer_id: nil,
36 + default: false,
37 + expiration_month: nil,
38 + expiration_year: nil,
39 + expired: nil,
40 + image_url: nil,
41 + last_4: nil,
42 + payment_instrument_name: nil,
43 + source_description: nil,
44 + subscriptions: [],
45 + token: nil,
46 + updated_at: nil
47 + end
Loading more files…