mercadopago-sdk 3.3.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 518cbc2c53d00de1452bf210afff62915ba381a970d084ca42a848e5604fa582
4
- data.tar.gz: 85468b9a03305eb33e4b053a4aae7149cbacd1ceb33df494e25bf63391b2bfea
3
+ metadata.gz: fb7488c81eb88390ec65887c4f7626f51fabd3a268fec20e37a21c4bcb857551
4
+ data.tar.gz: 80ffcd3be59f116220171f3b4b053c0b48a5e222a09c22e4e9063ef6d8514826
5
5
  SHA512:
6
- metadata.gz: 59839cc98cb80e2718b5694f05559b0a73fe23f04b953c0d172bb80b0609c220f673bd88952326eab551bcd52edd0beec0cb2173c188b9ea9cace45c5513b75b
7
- data.tar.gz: 4e2e68a2fef69a84eafba9c8fa6b877d214f953e764d26525f48dca5cb812686195fe7fea80085704c8827de1d023fe385c366dede92156a98e680d51ae8dbce
6
+ metadata.gz: 6fa0b01c59f95ee75586f5685212a899fd717963230cafafd237b2b8d981f7ecb75327446419323f88933e50fcc85850efbddafcb0bdd6b630de1d043b77fd6a
7
+ data.tar.gz: 101c97f483a49e8317b8ab9748e2433f42a0334969185fa26f21ee61ef0d139883cb22aa80618565dcea6702195868ea886893132b650b4dd2287b5c8c8d59c0
@@ -1,43 +1,45 @@
1
- name: Ruby
1
+ name: CI
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [ master ]
5
+ branches: ["master"]
6
6
  pull_request:
7
- branches: [ master ]
7
+ branches: ["master"]
8
8
 
9
9
  jobs:
10
10
  test:
11
+ name: Test on Ruby ${{ matrix.ruby-version }}
11
12
  runs-on: ubuntu-latest
12
- container: ruby:3.4
13
+ container: ruby:${{ matrix.ruby-version }}
14
+
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ ruby-version: ["3.3", "3.4"]
13
19
 
14
20
  steps:
15
- - name: Checkout code
16
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
17
- with:
18
- ref: ${{ github.event.pull_request.head.ref }}
19
- repository: ${{ github.event.pull_request.head.repo.full_name }}
20
-
21
- - name: Cache gems
22
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
23
- with:
24
- path: vendor/bundle
25
- key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
26
- restore-keys: |
27
- ${{ runner.os }}-gems-
28
-
29
- - name: Install dependencies
30
- run: |
31
- bundle config set --local path vendor/bundle
32
- bundle install
33
-
34
- - name: Rubocop
35
- run: bundle exec rubocop lib
36
-
37
- # Integration tests disabled: they require a valid MercadoPago ACCESS_TOKEN
38
- # that is not available in the CI environment. To run them locally:
39
- # ACCESS_TOKEN=<your_token> bundle exec rake
40
- # - name: Run tests
41
- # run: bundle exec rake
42
- # env:
43
- # ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN_V2 }}
21
+ - name: Checkout code
22
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4
23
+
24
+ - name: Configure git safe directory
25
+ run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
26
+
27
+ - name: Install dependencies
28
+ run: bundle install
29
+
30
+ - name: Lint with Rubocop
31
+ run: bundle exec rubocop lib
32
+
33
+ - name: Run unit tests
34
+ run: bundle exec rake test
35
+
36
+ - name: Dependency audit
37
+ run: |
38
+ gem install bundler-audit --no-document
39
+ bundle-audit check --update
40
+
41
+ - name: Dependency review
42
+ if: github.event_name == 'pull_request'
43
+ uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v4
44
+ with:
45
+ fail-on-severity: high
@@ -2,7 +2,7 @@ name: Release SDK - Publish Gem
2
2
 
3
3
  on:
4
4
  release:
5
- types: [created]
5
+ types: [published]
6
6
 
7
7
  jobs:
8
8
  release:
@@ -16,12 +16,12 @@ jobs:
16
16
  - name: Checkout code
17
17
  uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
18
18
 
19
- - name: Install dependencies
20
- run: bundle install
21
-
22
19
  - name: Configure git safe directory
23
20
  run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
24
21
 
22
+ - name: Install dependencies
23
+ run: bundle install
24
+
25
25
  - name: Build gem
26
26
  run: gem build *.gemspec
27
27
 
@@ -29,6 +29,3 @@ jobs:
29
29
  env:
30
30
  GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
31
31
  run: gem push *.gem
32
-
33
- - name: Wait for release to propagate
34
- run: gem install rubygems-await
data/.gitignore CHANGED
@@ -2,5 +2,6 @@
2
2
  bin/
3
3
  config/*yml
4
4
  pkg/
5
+ vendor/
5
6
  *.log
6
7
  *.gem
data/.rubocop_todo.yml CHANGED
@@ -48,8 +48,14 @@ Metrics/MethodLength:
48
48
 
49
49
  # Offense count: 3
50
50
  # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
51
+ Metrics/ModuleLength:
52
+ Exclude:
53
+ - 'lib/mercadopago/resources/order/request.rb'
54
+
51
55
  Metrics/ParameterLists:
52
56
  Max: 7
57
+ Exclude:
58
+ - 'lib/mercadopago/resources/order/request.rb'
53
59
 
54
60
  # Offense count: 1
55
61
  Naming/AccessorMethodName:
data/CHANGELOG.md CHANGED
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
5
5
  This project follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6
6
  and [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.4.0] - 2026-08-11
9
+
10
+ ### Added
11
+ - **Automatic Payments example**: two-step recurring flow ([#156](https://github.com/mercadopago/sdk-ruby/pull/156))
12
+ - **Pagination**: support `data` key for Orders v2 API and string paging totals ([#156](https://github.com/mercadopago/sdk-ruby/pull/156))
13
+
14
+ ### Fixed
15
+ - **Stored credential**: rename `prev_transaction_ref` to `previous_transaction_reference` ([#156](https://github.com/mercadopago/sdk-ruby/pull/156))
16
+ - **`Iterator#call`**: use keyword args for Ruby 4.0 strict kwarg separation ([#156](https://github.com/mercadopago/sdk-ruby/pull/156))
17
+
18
+ ### CI
19
+ - Standardize CI/CD workflows ([#166](https://github.com/mercadopago/sdk-ruby/pull/166))
20
+ - Migrate tests to mock-based unit tests ([#166](https://github.com/mercadopago/sdk-ruby/pull/166))
21
+ - Fix SDK bugs discovered during mock test migration ([#166](https://github.com/mercadopago/sdk-ruby/pull/166))
22
+ - Fix Ruby CI: drop 3.2 matrix (gemspec requires >=3.3), add `safe.directory` ([#166](https://github.com/mercadopago/sdk-ruby/pull/166))
23
+
8
24
  ## [3.3.0] - 2026-08-04
9
25
 
10
26
  ### Added
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mercadopago-sdk (3.3.0)
4
+ mercadopago-sdk (3.4.0)
5
5
  faraday (~> 2.0)
6
6
  json (~> 2.5)
7
7
 
@@ -0,0 +1,162 @@
1
+ require_relative '../../lib/mercadopago'
2
+
3
+ # Mercado Pago Create Order — Automatic Payments (recurring charges).
4
+ #
5
+ # Demonstrates the two-step Automatic Payments flow:
6
+ # 1. First payment — CVV-validated charge that registers the card credential.
7
+ # 2. Recurring charge — subsequent MIT charge without CVV, referencing step 1.
8
+ #
9
+ # Prerequisites:
10
+ # - A customer created via POST /v1/customers → customer_id
11
+ # - A payment profile created via POST /v1/customers/{id}/payment-profiles → payment_profile_id
12
+
13
+ sdk = Mercadopago::SDK.new('<ACCESS_TOKEN>')
14
+
15
+ # ── Step 1: First payment ─────────────────────────────────────────────────────
16
+ # Registers the card credential with first_payment: true.
17
+ # No prev_transaction_ref is needed on the first charge.
18
+ def create_first_payment(sdk, customer_id:, payment_profile_id:, payer_email:, card_token:)
19
+ request = {
20
+ type: 'online',
21
+ processing_mode: 'automatic',
22
+ total_amount: '100.00',
23
+ external_reference: 'subscription-001-payment-1',
24
+ payer: {
25
+ email: payer_email,
26
+ customer_id: customer_id
27
+ },
28
+ transactions: {
29
+ payments: [
30
+ {
31
+ amount: '100.00',
32
+ payment_method: {
33
+ id: 'master',
34
+ type: 'credit_card',
35
+ token: card_token,
36
+ installments: 1
37
+ },
38
+ automatic_payments: {
39
+ payment_profile_id: payment_profile_id
40
+ },
41
+ stored_credential: {
42
+ payment_initiator: 'customer',
43
+ reason: 'recurring',
44
+ first_payment: true
45
+ }
46
+ }
47
+ ]
48
+ }
49
+ }
50
+
51
+ custom_headers = { 'X-Idempotency-Key': '<IDEMPOTENCY_KEY_FIRST>' }
52
+ request_options = Mercadopago::RequestOptions.new(custom_headers: custom_headers)
53
+
54
+ sdk.order.create(request, request_options: request_options)
55
+ rescue StandardError => e
56
+ puts e.message
57
+ nil
58
+ end
59
+
60
+ # ── Step 2: Recurring charge ──────────────────────────────────────────────────
61
+ # Subsequent MIT charge — no card token needed, uses the payment profile.
62
+ # prev_transaction_ref links this charge to the original authorization.
63
+ def create_recurring_charge(sdk,
64
+ customer_id:,
65
+ payment_profile_id:,
66
+ payer_email:,
67
+ previous_transaction_reference:,
68
+ sequence_number:)
69
+ request = {
70
+ type: 'online',
71
+ processing_mode: 'automatic_async',
72
+ total_amount: '100.00',
73
+ external_reference: "subscription-001-payment-#{sequence_number}",
74
+ payer: {
75
+ email: payer_email,
76
+ customer_id: customer_id
77
+ },
78
+ transactions: {
79
+ payments: [
80
+ {
81
+ amount: '100.00',
82
+ automatic_payments: {
83
+ payment_profile_id: payment_profile_id,
84
+ retries: 3,
85
+ schedule_date: '2026-09-01T00:00:00.000-04:00',
86
+ due_date: '2026-09-05T00:00:00.000-04:00'
87
+ },
88
+ stored_credential: {
89
+ payment_initiator: 'merchant',
90
+ reason: 'recurring',
91
+ first_payment: false,
92
+ previous_transaction_reference: previous_transaction_reference
93
+ },
94
+ subscription_data: {
95
+ invoice_id: "INV-00#{sequence_number}",
96
+ billing_date: '2026-08-01',
97
+ subscription_sequence: {
98
+ number: sequence_number,
99
+ total: 12
100
+ },
101
+ invoice_period: {
102
+ type: 'monthly',
103
+ period: 1
104
+ }
105
+ }
106
+ }
107
+ ]
108
+ }
109
+ }
110
+
111
+ custom_headers = { 'X-Idempotency-Key': "<IDEMPOTENCY_KEY_RECURRING_#{sequence_number}>" }
112
+ request_options = Mercadopago::RequestOptions.new(custom_headers: custom_headers)
113
+
114
+ sdk.order.create(request, request_options: request_options)
115
+ rescue StandardError => e
116
+ puts e.message
117
+ nil
118
+ end
119
+
120
+ # ── Run the flow ──────────────────────────────────────────────────────────────
121
+ customer_id = '<CUSTOMER_ID>'
122
+ payment_profile_id = '<PAYMENT_PROFILE_ID>'
123
+ payer_email = '<PAYER_EMAIL>'
124
+ card_token = '<CARD_TOKEN>'
125
+
126
+ # First payment
127
+ first_result = create_first_payment(
128
+ sdk,
129
+ customer_id: customer_id,
130
+ payment_profile_id: payment_profile_id,
131
+ payer_email: payer_email,
132
+ card_token: card_token
133
+ )
134
+
135
+ if first_result
136
+ first_order = first_result[:response]
137
+ puts "First payment order ID: #{first_order['id']}"
138
+ puts "Status: #{first_order['status']}"
139
+
140
+ # Save the payment ID for the next recurring charge
141
+ first_payment_id = first_order.dig('transactions', 'payments', 0, 'id')
142
+ puts "First payment ID (save for next charge): #{first_payment_id}"
143
+
144
+ # Recurring charge
145
+ if first_payment_id
146
+ recurring_result = create_recurring_charge(
147
+ sdk,
148
+ customer_id: customer_id,
149
+ payment_profile_id: payment_profile_id,
150
+ payer_email: payer_email,
151
+ previous_transaction_reference: first_payment_id,
152
+ sequence_number: 2
153
+ )
154
+
155
+ if recurring_result
156
+ recurring_order = recurring_result[:response]
157
+ puts "\nRecurring charge order ID: #{recurring_order['id']}"
158
+ puts "Status: #{recurring_order['status']}"
159
+ puts "Status detail: #{recurring_order['status_detail']}"
160
+ end
161
+ end
162
+ end
@@ -23,7 +23,7 @@ module Mercadopago
23
23
  # @param request_options [RequestOptions, nil] per-call configuration override
24
24
  # @return [Hash{Symbol => Object}] +:status+ and +:response+ with refund details
25
25
  def create_all(advanced_payment_id, request_options: nil)
26
- _post(uri: "/v1/advanced_payments/#{_path_param(advanced_payment_id)}/refunds", request_options: request_options)
26
+ _post(uri: "/v1/advanced_payments/#{_path_param(advanced_payment_id)}/refunds", data: nil, request_options: request_options)
27
27
  end
28
28
 
29
29
  # Refunds a single disbursement (full or partial).