From f718b5062095d018014735e712f040d11a897ad3 Mon Sep 17 00:00:00 2001 From: Justintime50 <39606064+Justintime50@users.noreply.github.com> Date: Thu, 24 Sep 2026 09:57:39 -0600 Subject: [PATCH] chore: remove deprecated, unused add_credit_card function Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CHANGELOG.md | 6 + lib/easypost/services/referral_customer.rb | 71 ------ ...it_card_to_a_referral_customer_account.yml | 210 ----------------- ..._when_we_cannot_send_details_to_Stripe.yml | 212 ------------------ ...ieves_EasyPost_s_Stripe_public_API_key.yml | 68 ++++++ spec/referral_customer_spec.rb | 48 +--- 6 files changed, 84 insertions(+), 531 deletions(-) delete mode 100644 spec/cassettes/referral_customer/EasyPost_Services_ReferralCustomer_add_credit_card_adds_a_credit_card_to_a_referral_customer_account.yml delete mode 100644 spec/cassettes/referral_customer/EasyPost_Services_ReferralCustomer_raises_an_error_when_we_cannot_send_details_to_Stripe.yml create mode 100644 spec/cassettes/referral_customer/EasyPost_Services_ReferralCustomer_retrieve_easypost_stripe_api_key_retrieves_EasyPost_s_Stripe_public_API_key.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 9199909f..dc76bfef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## Next Release + +- Removes the deprecated, unusable `add_credit_card` function + - Stripe has disabled the ability to pass plain credit card details over the wire and now requires using [Stripe.js/Elements/Checkout](https://support.stripe.com/questions/card-tokenization-restrictions-using-publishable-keys). Follow the [Decentralized (EasyPost-Manage Billing) Guide](https://docs.easypost.com/guides/get-started-with-forge/easypost-managed-billing-guide#referralcustomer-billing-management) for more details on the new flow to use. + - Makes `referral_customer.retrieve_easypost_stripe_api_key` public to help facilitate adding credit cards using Stripe.js + ## v7.7.0 (2026-06-25) - Adds `params` to `request_pin` ensuring users can pass `easypost_details` to the call diff --git a/lib/easypost/services/referral_customer.rb b/lib/easypost/services/referral_customer.rb index e1cb8d0e..507d1367 100644 --- a/lib/easypost/services/referral_customer.rb +++ b/lib/easypost/services/referral_customer.rb @@ -40,25 +40,6 @@ def get_next_page(collection, page_size = nil) all(params) end - # Add a credit card to EasyPost for a ReferralCustomer without needing a Stripe account. This function requires the ReferralCustomer User's API key. - def add_credit_card(referral_api_key, number, expiration_month, expiration_year, cvc, priority = 'primary') - easypost_stripe_api_key = retrieve_easypost_stripe_api_key - - begin - stripe_credit_card_token = create_stripe_token( - number, - expiration_month, - expiration_year, - cvc, - easypost_stripe_api_key, - ) - rescue StandardError - raise EasyPost::Errors::ExternalApiError.new(EasyPost::Constants::STRIPE_CARD_CREATE_FAILED) - end - - create_easypost_credit_card(referral_api_key, stripe_credit_card_token, priority) - end - # Add a credit card to EasyPost for a ReferralCustomer with a payment method ID from Stripe. This function requires the ReferralCustomer User's API key. def add_credit_card_from_stripe(referral_api_key, payment_method_id, priority = 'primary') params = { @@ -94,61 +75,9 @@ def add_bank_account_from_stripe(referral_api_key, financial_connections_id, man EasyPost::InternalUtilities::Json.convert_json_to_object(response) end - private - # Retrieve EasyPost's Stripe public API key. def retrieve_easypost_stripe_api_key response = @client.make_request(:get, 'partners/stripe_public_key', nil, 'beta') response['public_key'] end - - # Get credit card token from Stripe. - def create_stripe_token(number, expiration_month, expiration_year, - cvc, easypost_stripe_token) - headers = { - # This Stripe endpoint only accepts URL form encoded bodies. - Authorization: "Bearer #{easypost_stripe_token}", - 'Content-type': 'application/x-www-form-urlencoded', - } - - credit_card_hash = { - card: { - number: number, - exp_month: expiration_month, - exp_year: expiration_year, - cvc: cvc, - }, - } - - form_encoded_params = EasyPost::InternalUtilities.form_encode_params(credit_card_hash) - - uri = URI.parse('https://api.stripe.com/v1/tokens') - http = Net::HTTP.new(uri.host, uri.port) - http.use_ssl = true - request = Net::HTTP::Post.new(uri.request_uri, headers) - query = URI.encode_www_form(form_encoded_params) - - response = http.request(request, query) - response_json = JSON.parse(response.body) - response_json['id'] - end - - # Submit Stripe credit card token to EasyPost. - def create_easypost_credit_card(referral_api_key, stripe_object_id, priority = 'primary') - wrapped_params = { - credit_card: { - stripe_object_id: stripe_object_id, - priority: priority, - }, - } - referral_client = EasyPost::Client.new(api_key: referral_api_key) - response = referral_client.make_request( - :post, - 'credit_cards', - wrapped_params, - 'beta', - ) - - EasyPost::InternalUtilities::Json.convert_json_to_object(response) - end end diff --git a/spec/cassettes/referral_customer/EasyPost_Services_ReferralCustomer_add_credit_card_adds_a_credit_card_to_a_referral_customer_account.yml b/spec/cassettes/referral_customer/EasyPost_Services_ReferralCustomer_add_credit_card_adds_a_credit_card_to_a_referral_customer_account.yml deleted file mode 100644 index df03eeeb..00000000 --- a/spec/cassettes/referral_customer/EasyPost_Services_ReferralCustomer_add_credit_card_adds_a_credit_card_to_a_referral_customer_account.yml +++ /dev/null @@ -1,210 +0,0 @@ ---- -http_interactions: -- request: - method: get - uri: https://api.easypost.com/beta/partners/stripe_public_key - body: - encoding: US-ASCII - string: '' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: "" - Host: - - api.easypost.com - Content-Type: - - application/json - Authorization: "" - response: - status: - code: 200 - message: OK - headers: - X-Frame-Options: - - SAMEORIGIN - X-Xss-Protection: - - 1; mode=block - X-Content-Type-Options: - - nosniff - X-Download-Options: - - noopen - X-Permitted-Cross-Domain-Policies: - - none - Referrer-Policy: - - strict-origin-when-cross-origin - X-Ep-Request-Uuid: - - d044fa7b66a7dadce799e104005a0680 - Cache-Control: - - private, no-cache, no-store - Pragma: - - no-cache - Expires: - - '0' - Content-Type: - - application/json; charset=utf-8 - X-Runtime: - - '0.029990' - Vary: - - Origin - Transfer-Encoding: - - chunked - X-Node: - - bigweb36nuq - X-Version-Label: - - easypost-202407291746-57ea285141-master - X-Backend: - - easypost - X-Proxied: - - extlb1nuq fa152d4755 - - intlb4nuq c0f5e722d1 - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload - body: - encoding: UTF-8 - string: '{"public_key":"pk_x3JSr5eOVWNTLRej8cZDde9VQ0AT5"}' - recorded_at: Mon, 29 Jul 2024 18:09:32 GMT -- request: - method: post - uri: https://api.stripe.com/v1/tokens - body: - encoding: US-ASCII - string: card%5Bnumber%5D=&card%5Bexp_month%5D=05&card%5Bexp_year%5D=2028&card%5Bcvc%5D= - headers: - Authorization: "" - Content-Type: - - application/x-www-form-urlencoded - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: "" - response: - status: - code: 200 - message: OK - headers: - Server: - - nginx - Date: - - Mon, 29 Jul 2024 18:09:32 GMT - Content-Type: - - application/json - Content-Length: - - '787' - Connection: - - keep-alive - Access-Control-Allow-Credentials: - - 'true' - Access-Control-Allow-Methods: - - GET,HEAD,PUT,PATCH,POST,DELETE - Access-Control-Allow-Origin: - - "*" - Access-Control-Expose-Headers: - - Request-Id, Stripe-Manage-Version, Stripe-Should-Retry, X-Stripe-External-Auth-Required, - X-Stripe-Privileged-Session-Required - Access-Control-Max-Age: - - '300' - Cache-Control: - - no-cache, no-store - Content-Security-Policy: - - report-uri https://q.stripe.com/csp-report?p=v1%2Ftokens; block-all-mixed-content; - default-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; - img-src 'self'; script-src 'self' 'report-sample'; style-src 'self' - Cross-Origin-Opener-Policy-Report-Only: - - same-origin; report-to="coop" - Idempotency-Key: - - 6a764363-4e65-4824-a997-8b4cc888d845 - Original-Request: - - req_Zka8DhoeIjokKO - Report-To: - - '{"group":"coop","max_age":8640,"endpoints":[{"url":"https://q.stripe.com/coop-report?s=payins-bapi-srv"}],"include_subdomains":true}' - Reporting-Endpoints: - - coop="https://q.stripe.com/coop-report?s=payins-bapi-srv" - Request-Id: - - req_Zka8DhoeIjokKO - Stripe-Should-Retry: - - 'false' - Stripe-Version: - - '2020-08-27' - Vary: - - Origin - X-Content-Type-Options: - - nosniff - X-Stripe-Priority-Routing-Enabled: - - 'true' - X-Stripe-Routing-Context-Priority-Tier: - - livemode-critical - Strict-Transport-Security: - - max-age=63072000; includeSubDomains; preload - body: - encoding: UTF-8 - string: '{"id":"tok_0Phy0mDqT4huGUvdkK1ODUzX","object":"token","card":{"id":"card_0Phy0mDqT4huGUvdeOcPq6wi","object":"card","address_city":null,"address_country":null,"address_line1":null,"address_line1_check":null,"address_line2":null,"address_state":null,"address_zip":null,"address_zip_check":null,"brand":"Visa","country":"US","cvc_check":"unchecked","dynamic_last4":null,"exp_month":5,"exp_year":2028,"funding":"credit","last4":"6170","name":null,"networks":{"preferred":null},"tokenization_method":null,"wallet":null},"client_ip":"","created":1722276572,"livemode":true,"type":"card","used":false}' - recorded_at: Mon, 29 Jul 2024 18:09:32 GMT -- request: - method: post - uri: https://api.easypost.com/beta/credit_cards - body: - encoding: UTF-8 - string: '{"credit_card":{"stripe_object_id":"tok_0Phy0mDqT4huGUvdkK1ODUzX","priority":"primary"}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: "" - Host: - - api.easypost.com - Content-Type: - - application/json - Authorization: "" - response: - status: - code: 201 - message: Created - headers: - X-Frame-Options: - - SAMEORIGIN - X-Xss-Protection: - - 1; mode=block - X-Content-Type-Options: - - nosniff - X-Download-Options: - - noopen - X-Permitted-Cross-Domain-Policies: - - none - Referrer-Policy: - - strict-origin-when-cross-origin - X-Ep-Request-Uuid: - - d044fa7966a7dadde799e11d005a0753 - Cache-Control: - - private, no-cache, no-store - Pragma: - - no-cache - Expires: - - '0' - Content-Type: - - application/json; charset=utf-8 - X-Runtime: - - '2.329041' - Vary: - - Origin - Transfer-Encoding: - - chunked - X-Node: - - bigweb41nuq - X-Version-Label: - - easypost-202407291746-57ea285141-master - X-Backend: - - easypost - X-Proxied: - - extlb1nuq fa152d4755 - - intlb3nuq c0f5e722d1 - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload - body: - encoding: UTF-8 - string: '{"id":"pm_d09256cba2f44be8819d6a5ca18c6128","disabled_at":null,"object":"CreditCard","name":null,"last4":"6170","exp_month":5,"exp_year":2028,"brand":"Visa","requires_mandate_collection":false}' - recorded_at: Mon, 29 Jul 2024 18:09:35 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/referral_customer/EasyPost_Services_ReferralCustomer_raises_an_error_when_we_cannot_send_details_to_Stripe.yml b/spec/cassettes/referral_customer/EasyPost_Services_ReferralCustomer_raises_an_error_when_we_cannot_send_details_to_Stripe.yml deleted file mode 100644 index 680489f2..00000000 --- a/spec/cassettes/referral_customer/EasyPost_Services_ReferralCustomer_raises_an_error_when_we_cannot_send_details_to_Stripe.yml +++ /dev/null @@ -1,212 +0,0 @@ ---- -http_interactions: -- request: - method: get - uri: https://api.easypost.com/beta/partners/stripe_public_key - body: - encoding: US-ASCII - string: '' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: "" - Host: - - api.easypost.com - Content-Type: - - application/json - Authorization: "" - response: - status: - code: 200 - message: OK - headers: - X-Frame-Options: - - SAMEORIGIN - X-Xss-Protection: - - 1; mode=block - X-Content-Type-Options: - - nosniff - X-Download-Options: - - noopen - X-Permitted-Cross-Domain-Policies: - - none - Referrer-Policy: - - strict-origin-when-cross-origin - X-Ep-Request-Uuid: - - d044fa7666a7dad4e799e0e10059fe1e - Cache-Control: - - private, no-cache, no-store - Pragma: - - no-cache - Expires: - - '0' - Content-Type: - - application/json; charset=utf-8 - X-Runtime: - - '0.028697' - Vary: - - Origin - Transfer-Encoding: - - chunked - X-Node: - - bigweb43nuq - X-Version-Label: - - easypost-202407291746-57ea285141-master - X-Backend: - - easypost - X-Canary: - - direct - X-Proxied: - - extlb1nuq fa152d4755 - - intlb3nuq c0f5e722d1 - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload - body: - encoding: UTF-8 - string: '{"public_key":"pk_x3JSr5eOVWNTLRej8cZDde9VQ0AT5"}' - recorded_at: Mon, 29 Jul 2024 18:09:24 GMT -- request: - method: post - uri: https://api.stripe.com/v1/tokens - body: - encoding: US-ASCII - string: card%5Bnumber%5D=&card%5Bexp_month%5D=05&card%5Bexp_year%5D=2028&card%5Bcvc%5D= - headers: - Authorization: "" - Content-Type: - - application/x-www-form-urlencoded - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: "" - response: - status: - code: 200 - message: OK - headers: - Server: - - nginx - Date: - - Mon, 29 Jul 2024 18:09:24 GMT - Content-Type: - - application/json - Content-Length: - - '787' - Connection: - - keep-alive - Access-Control-Allow-Credentials: - - 'true' - Access-Control-Allow-Methods: - - GET,HEAD,PUT,PATCH,POST,DELETE - Access-Control-Allow-Origin: - - "*" - Access-Control-Expose-Headers: - - Request-Id, Stripe-Manage-Version, Stripe-Should-Retry, X-Stripe-External-Auth-Required, - X-Stripe-Privileged-Session-Required - Access-Control-Max-Age: - - '300' - Cache-Control: - - no-cache, no-store - Content-Security-Policy: - - report-uri https://q.stripe.com/csp-report?p=v1%2Ftokens; block-all-mixed-content; - default-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; - img-src 'self'; script-src 'self' 'report-sample'; style-src 'self' - Cross-Origin-Opener-Policy-Report-Only: - - same-origin; report-to="coop" - Idempotency-Key: - - 65b327b0-bfbf-459f-817f-ffa84327948b - Original-Request: - - req_fhfsXKCnj8KiUE - Report-To: - - '{"group":"coop","max_age":8640,"endpoints":[{"url":"https://q.stripe.com/coop-report?s=payins-bapi-srv"}],"include_subdomains":true}' - Reporting-Endpoints: - - coop="https://q.stripe.com/coop-report?s=payins-bapi-srv" - Request-Id: - - req_fhfsXKCnj8KiUE - Stripe-Should-Retry: - - 'false' - Stripe-Version: - - '2020-08-27' - Vary: - - Origin - X-Content-Type-Options: - - nosniff - X-Stripe-Priority-Routing-Enabled: - - 'true' - X-Stripe-Routing-Context-Priority-Tier: - - livemode-critical - Strict-Transport-Security: - - max-age=63072000; includeSubDomains; preload - body: - encoding: UTF-8 - string: '{"id":"tok_0Phy0eDqT4huGUvdiiEaw9M5","object":"token","card":{"id":"card_0Phy0eDqT4huGUvdOrZiggU4","object":"card","address_city":null,"address_country":null,"address_line1":null,"address_line1_check":null,"address_line2":null,"address_state":null,"address_zip":null,"address_zip_check":null,"brand":"Visa","country":"US","cvc_check":"unchecked","dynamic_last4":null,"exp_month":5,"exp_year":2028,"funding":"credit","last4":"6170","name":null,"networks":{"preferred":null},"tokenization_method":null,"wallet":null},"client_ip":"","created":1722276564,"livemode":true,"type":"card","used":false}' - recorded_at: Mon, 29 Jul 2024 18:09:24 GMT -- request: - method: post - uri: https://api.easypost.com/beta/credit_cards - body: - encoding: UTF-8 - string: '{"credit_card":{"stripe_object_id":"tok_0Phy0eDqT4huGUvdiiEaw9M5","priority":"primary"}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: "" - Host: - - api.easypost.com - Content-Type: - - application/json - Authorization: "" - response: - status: - code: 201 - message: Created - headers: - X-Frame-Options: - - SAMEORIGIN - X-Xss-Protection: - - 1; mode=block - X-Content-Type-Options: - - nosniff - X-Download-Options: - - noopen - X-Permitted-Cross-Domain-Policies: - - none - Referrer-Policy: - - strict-origin-when-cross-origin - X-Ep-Request-Uuid: - - d044fa7966a7dad5e799e0e30059fefb - Cache-Control: - - private, no-cache, no-store - Pragma: - - no-cache - Expires: - - '0' - Content-Type: - - application/json; charset=utf-8 - X-Runtime: - - '2.432658' - Vary: - - Origin - Transfer-Encoding: - - chunked - X-Node: - - bigweb40nuq - X-Version-Label: - - easypost-202407291746-57ea285141-master - X-Backend: - - easypost - X-Proxied: - - extlb1nuq fa152d4755 - - intlb4nuq c0f5e722d1 - Strict-Transport-Security: - - max-age=31536000; includeSubDomains; preload - body: - encoding: UTF-8 - string: '{"id":"pm_0af17f09a34749ffbaee4e8bff99fc11","disabled_at":null,"object":"CreditCard","name":null,"last4":"6170","exp_month":5,"exp_year":2028,"brand":"Visa","requires_mandate_collection":false}' - recorded_at: Mon, 29 Jul 2024 18:09:27 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/referral_customer/EasyPost_Services_ReferralCustomer_retrieve_easypost_stripe_api_key_retrieves_EasyPost_s_Stripe_public_API_key.yml b/spec/cassettes/referral_customer/EasyPost_Services_ReferralCustomer_retrieve_easypost_stripe_api_key_retrieves_EasyPost_s_Stripe_public_API_key.yml new file mode 100644 index 00000000..292403aa --- /dev/null +++ b/spec/cassettes/referral_customer/EasyPost_Services_ReferralCustomer_retrieve_easypost_stripe_api_key_retrieves_EasyPost_s_Stripe_public_API_key.yml @@ -0,0 +1,68 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.easypost.com/beta/partners/stripe_public_key + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: "" + Host: + - api.easypost.com + Content-Type: + - application/json + Authorization: "" + response: + status: + code: 200 + message: OK + headers: + X-Frame-Options: + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Permitted-Cross-Domain-Policies: + - none + Referrer-Policy: + - strict-origin-when-cross-origin + X-Ep-Request-Uuid: + - a75592ff6ab54850e2b8ff93022610a1 + Cache-Control: + - private, no-cache, no-store + Pragma: + - no-cache + Expires: + - '0' + Content-Type: + - application/json; charset=utf-8 + X-Runtime: + - '0.024659' + Vary: + - Origin + Transfer-Encoding: + - chunked + X-Node: + - web127azw + X-Version-Label: + - easypost-202609241501-949351e54f-main + X-Backend: + - easypost + X-Proxied: + - extlb1azw 07fb4d8f06 + - intlb1azw f29267e751 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + body: + encoding: UTF-8 + string: '{"public_key":"pk_x3JSr5eOVWNTLRej8cZDde9VQ0AT5"}' + recorded_at: Thu, 24 Sep 2026 15:57:04 GMT +recorded_with: VCR 6.4.0 diff --git a/spec/referral_customer_spec.rb b/spec/referral_customer_spec.rb index 6fb4497a..503f1bf3 100644 --- a/spec/referral_customer_spec.rb +++ b/spec/referral_customer_spec.rb @@ -78,44 +78,6 @@ end end - describe '.add_credit_card' do - it 'adds a credit card to a referral customer account' do - # We override the VCR config here since it cannot match the URL due to data scrubbing - # rubocop:disable Layout/LineLength - VCR.use_cassette( - 'referral_customer/EasyPost_Services_ReferralCustomer_add_credit_card_adds_a_credit_card_to_a_referral_customer_account', - match_requests_on: [:method, :uri], - ) do - # rubocop:enable Layout/LineLength - credit_card = client.referral_customer.add_credit_card( - REFERRAL_CUSTOMER_PROD_API_KEY, - Fixture.credit_card_details['number'], - Fixture.credit_card_details['expiration_month'], - Fixture.credit_card_details['expiration_year'], - Fixture.credit_card_details['cvc'], - ) - - expect(credit_card.id).to match('pm_') - expect(credit_card.last4).to match('6170') - end - end - end - - it 'raises an error when we cannot send details to Stripe' do - allow(client.referral_customer).to receive(:create_stripe_token).and_raise(StandardError) - allow(client.referral_customer).to receive(:retrieve_easypost_stripe_api_key) - - expect { - client.referral_customer.add_credit_card( - REFERRAL_CUSTOMER_PROD_API_KEY, - Fixture.credit_card_details['number'], - Fixture.credit_card_details['expiration_month'], - Fixture.credit_card_details['expiration_year'], - Fixture.credit_card_details['cvc'], - ) - }.to raise_error(StandardError).with_message('Could not send card details to Stripe, please try again later.') - end - describe '.add_credit_card_from_stripe' do it 'raises an error when adding a credit card from Stripe fails' do # This test requires a referral customer's production API key via REFERRAL_CUSTOMER_PROD_API_KEY. @@ -146,4 +108,14 @@ ) end end + + describe '.retrieve_easypost_stripe_api_key' do + it "retrieves EasyPost's Stripe public API key" do + # This test requires a partner user's production API key via PARTNER_USER_PROD_API_KEY. + public_key = client.referral_customer.retrieve_easypost_stripe_api_key + + expect(public_key).to be_a(String) + expect(public_key).to start_with('pk_') + end + end end