active_merchant_ecpay 0.1.2 → 0.2.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 +5 -5
- data/.github/workflows/publish.yml +121 -0
- data/.github/workflows/test.yml +47 -0
- data/.gitignore +2 -0
- data/CHANGELOG.md +42 -0
- data/CLAUDE.md +20 -0
- data/README.md +126 -50
- data/Rakefile +1 -0
- data/active_merchant_ecpay.gemspec +7 -4
- data/gemfiles/rails_7.0.gemfile +19 -0
- data/gemfiles/rails_7.1.gemfile +19 -0
- data/gemfiles/rails_7.2.gemfile +16 -0
- data/gemfiles/rails_8.0.gemfile +16 -0
- data/gemfiles/rails_8.1.gemfile +16 -0
- data/lib/active_merchant_ecpay/version.rb +1 -1
- metadata +52 -35
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 56b85be12292253c0939edcc92e46e146fc283c499a2472ce117edfa57e0f0f0
|
|
4
|
+
data.tar.gz: 5086c6c4bcbaa25a8b62fe47b72cf651d27589f1ad55675d2c601f87c788659f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 58a03448ac707c0e4cd1d47d8d153b1a7446f8ee2303a8338357f4d6e5c66d0e7d3c2e619e3651278f69f5533aa79ed35ef29056955cae4aed02090cb008a815
|
|
7
|
+
data.tar.gz: 125668f6a3bfbef5d0671d80da43a7f2a61f02e5b76f0f07ca6f25212da003923bf57035231666c63674e2a7d6ccbaaad2cbacb477f76db1663b935fc298a780
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
name: Publish gem
|
|
2
|
+
|
|
3
|
+
# master 上 gemspec 版本號尚未發佈到 rubygems.org 時,自動以 Trusted Publishing (OIDC) 發佈。
|
|
4
|
+
# 版本已存在則跳過;不使用任何儲存的 RubyGems API key。
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
branches:
|
|
8
|
+
- master
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: publish-gem-${{ github.repository }}
|
|
16
|
+
cancel-in-progress: false
|
|
17
|
+
|
|
18
|
+
env:
|
|
19
|
+
# 與 test.yml 矩陣中的 Ruby 3.4 / Rails 8.0 組合一致(gemfiles/ 的 lockfile 不納入版控,由 CI 解析)
|
|
20
|
+
RUBY_VERSION: '3.4.11'
|
|
21
|
+
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/rails_8.0.gemfile
|
|
22
|
+
GEM_NAME: active_merchant_ecpay
|
|
23
|
+
GEMSPEC: active_merchant_ecpay.gemspec
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
check:
|
|
27
|
+
name: Check version on rubygems.org
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
outputs:
|
|
30
|
+
should_publish: ${{ steps.check.outputs.should_publish }}
|
|
31
|
+
gem_name: ${{ steps.spec.outputs.name }}
|
|
32
|
+
gem_version: ${{ steps.spec.outputs.version }}
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
35
|
+
with:
|
|
36
|
+
persist-credentials: false
|
|
37
|
+
|
|
38
|
+
- uses: ruby/setup-ruby@b1da4809b005e0178fe08a1d57317bffc00b7b4c # v1.332.0
|
|
39
|
+
with:
|
|
40
|
+
ruby-version: ${{ env.RUBY_VERSION }}
|
|
41
|
+
|
|
42
|
+
- name: Read gem name and version from gemspec
|
|
43
|
+
id: spec
|
|
44
|
+
run: |
|
|
45
|
+
ruby -e 'spec = Gem::Specification.load(ENV.fetch("GEMSPEC")) or abort("cannot load #{ENV["GEMSPEC"]}"); abort("gemspec name #{spec.name} != #{ENV["GEM_NAME"]}") unless spec.name == ENV["GEM_NAME"]; puts "name=#{spec.name}"; puts "version=#{spec.version}"' >> "$GITHUB_OUTPUT"
|
|
46
|
+
cat "$GITHUB_OUTPUT"
|
|
47
|
+
|
|
48
|
+
- name: Check whether this version already exists on rubygems.org
|
|
49
|
+
id: check
|
|
50
|
+
env:
|
|
51
|
+
GEM_NAME: ${{ steps.spec.outputs.name }}
|
|
52
|
+
GEM_VERSION: ${{ steps.spec.outputs.version }}
|
|
53
|
+
run: |
|
|
54
|
+
set -euo pipefail
|
|
55
|
+
status=$(curl -sS -o versions.json -w '%{http_code}' "https://rubygems.org/api/v1/versions/${GEM_NAME}.json")
|
|
56
|
+
if [ "$status" = "404" ]; then
|
|
57
|
+
echo "Gem ${GEM_NAME} not found on rubygems.org; will publish."
|
|
58
|
+
echo "should_publish=true" >> "$GITHUB_OUTPUT"
|
|
59
|
+
exit 0
|
|
60
|
+
fi
|
|
61
|
+
if [ "$status" != "200" ]; then
|
|
62
|
+
echo "::error::rubygems.org API returned HTTP ${status}"
|
|
63
|
+
exit 1
|
|
64
|
+
fi
|
|
65
|
+
if jq -e --arg v "$GEM_VERSION" 'any(.[]; .number == $v)' versions.json > /dev/null; then
|
|
66
|
+
echo "${GEM_NAME} ${GEM_VERSION} already on rubygems.org; skip publish."
|
|
67
|
+
echo "should_publish=false" >> "$GITHUB_OUTPUT"
|
|
68
|
+
else
|
|
69
|
+
echo "${GEM_NAME} ${GEM_VERSION} not on rubygems.org yet; will publish."
|
|
70
|
+
echo "should_publish=true" >> "$GITHUB_OUTPUT"
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
test:
|
|
74
|
+
name: Test (Ruby 3.4 / Rails 8.0)
|
|
75
|
+
needs: check
|
|
76
|
+
if: needs.check.outputs.should_publish == 'true'
|
|
77
|
+
runs-on: ubuntu-latest
|
|
78
|
+
steps:
|
|
79
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
80
|
+
with:
|
|
81
|
+
persist-credentials: false
|
|
82
|
+
|
|
83
|
+
- uses: ruby/setup-ruby@b1da4809b005e0178fe08a1d57317bffc00b7b4c # v1.332.0
|
|
84
|
+
with:
|
|
85
|
+
ruby-version: ${{ env.RUBY_VERSION }}
|
|
86
|
+
bundler-cache: true
|
|
87
|
+
|
|
88
|
+
- run: bundle exec rake t
|
|
89
|
+
|
|
90
|
+
publish:
|
|
91
|
+
name: Publish ${{ needs.check.outputs.gem_name }} ${{ needs.check.outputs.gem_version }}
|
|
92
|
+
needs: [check, test]
|
|
93
|
+
if: needs.check.outputs.should_publish == 'true' && github.ref == 'refs/heads/master'
|
|
94
|
+
runs-on: ubuntu-latest
|
|
95
|
+
environment: gem-publish
|
|
96
|
+
permissions:
|
|
97
|
+
id-token: write # Trusted Publishing (OIDC)
|
|
98
|
+
contents: write # rake release 推送 vX.Y.Z tag
|
|
99
|
+
steps:
|
|
100
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
101
|
+
with:
|
|
102
|
+
persist-credentials: false
|
|
103
|
+
|
|
104
|
+
- uses: ruby/setup-ruby@b1da4809b005e0178fe08a1d57317bffc00b7b4c # v1.332.0
|
|
105
|
+
with:
|
|
106
|
+
ruby-version: ${{ env.RUBY_VERSION }}
|
|
107
|
+
bundler-cache: true
|
|
108
|
+
|
|
109
|
+
# setup-ruby 的 bundler-cache 會把 BUNDLE_PATH 等設定寫進 .bundle/config,
|
|
110
|
+
# 若該檔被 git 追蹤,rake release 的 guard_clean 會判定工作目錄不乾淨。
|
|
111
|
+
# 目前此 repo 沒有追蹤任何 .bundle/config;這一步對「有追蹤才標記」做容錯處理,
|
|
112
|
+
# 日後若加入 gemfiles/.bundle/config 或 .bundle/config 也不會讓發佈失敗。
|
|
113
|
+
- name: Ignore CI-only bundler config change
|
|
114
|
+
run: |
|
|
115
|
+
git status --porcelain
|
|
116
|
+
git ls-files -z '*.bundle/config' | xargs -0 -r git update-index --assume-unchanged
|
|
117
|
+
git status --porcelain
|
|
118
|
+
|
|
119
|
+
# 透過 rubygems/configure-rubygems-credentials 取得短效 OIDC token,
|
|
120
|
+
# 再執行 bundle exec rake release(build、建立並推送 vX.Y.Z tag、push gem)
|
|
121
|
+
- uses: rubygems/release-gem@7f9650160c1a4e7989fdc9855807bdbd421d8b6b # v1.4.1
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ master ]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: Ruby ${{ matrix.ruby }} / Rails ${{ matrix.rails }}
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
ruby: ["3.0", "3.1", "3.2", "3.3", "3.4"]
|
|
20
|
+
rails: ["7.0", "7.1", "7.2", "8.0", "8.1"]
|
|
21
|
+
exclude:
|
|
22
|
+
# Rails 7.2 需要 Ruby >= 3.1
|
|
23
|
+
- ruby: "3.0"
|
|
24
|
+
rails: "7.2"
|
|
25
|
+
# Rails 8.0 / 8.1 需要 Ruby >= 3.2
|
|
26
|
+
- ruby: "3.0"
|
|
27
|
+
rails: "8.0"
|
|
28
|
+
- ruby: "3.0"
|
|
29
|
+
rails: "8.1"
|
|
30
|
+
- ruby: "3.1"
|
|
31
|
+
rails: "8.0"
|
|
32
|
+
- ruby: "3.1"
|
|
33
|
+
rails: "8.1"
|
|
34
|
+
env:
|
|
35
|
+
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/rails_${{ matrix.rails }}.gemfile
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
38
|
+
with:
|
|
39
|
+
persist-credentials: false
|
|
40
|
+
|
|
41
|
+
- uses: ruby/setup-ruby@b1da4809b005e0178fe08a1d57317bffc00b7b4c # v1.332.0
|
|
42
|
+
with:
|
|
43
|
+
ruby-version: ${{ matrix.ruby }}
|
|
44
|
+
bundler-cache: true
|
|
45
|
+
|
|
46
|
+
- name: Run tests
|
|
47
|
+
run: bundle exec rake t
|
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
Release dates are the dates the version was published on [rubygems.org](https://rubygems.org/gems/active_merchant_ecpay).
|
|
9
|
+
|
|
10
|
+
## [Unreleased]
|
|
11
|
+
|
|
12
|
+
> `lib/active_merchant_ecpay/version.rb` on `master` is already `0.2.0`, but that version is **not on rubygems.org yet**
|
|
13
|
+
> (the "Publish gem" run for it failed with "No trusted publisher configured for this workflow"), so it is listed here.
|
|
14
|
+
> Once 0.2.0 is published, rename this section to `## [0.2.0] - YYYY-MM-DD` and use the date shown on rubygems.org.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- Support for Rails 7.0, 7.1, 7.2, 8.0 and 8.1 on Ruby 3.0 – 3.4. `actionview` and `activesupport` (`>= 7.0`, `< 8.2`) are now runtime dependencies.
|
|
19
|
+
- RSpec specs for request building, `CheckMacValue`, notification checks and configuration; they never touch the network. SimpleCov coverage with `COVERAGE=1`.
|
|
20
|
+
- GitHub Actions: a Ruby × Rails test matrix (`test.yml`) and automatic publishing to RubyGems through Trusted Publishing (`publish.yml`).
|
|
21
|
+
- `CHANGELOG.md`, a full `README.md`, and documentation rules in `CLAUDE.md`.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- **Breaking:** requires Ruby `>= 3.0` (`required_ruby_version`); Rails older than 7.0 is no longer supported.
|
|
26
|
+
- Development dependencies were modernised (`bundler >= 2`, `rake >= 13`); `mocha` and the old `rails >= 2.3.14` development dependency were removed in favour of per-version `gemfiles/`.
|
|
27
|
+
|
|
28
|
+
## [0.1.2] - 2018-11-16
|
|
29
|
+
|
|
30
|
+
Versions `0.1.0` and `0.1.1` were never published to RubyGems, so their changes ship in this release.
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- ECPay (綠界科技) AIO checkout integration for ActiveMerchant / OffsitePayments: the `payment_service_for` form helper with `CheckMacValue` (MD5) generation, and `Notification` parsing / verification. Payment methods: credit card, ATM, CVS, barcode and Alipay constants. (0.1.0)
|
|
35
|
+
- `Notification#card4no`: last four digits of the credit card. (0.1.1)
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- Gemspec description and `require` clean-up (`money` is now required explicitly).
|
|
40
|
+
|
|
41
|
+
[Unreleased]: https://github.com/superlanding/active_merchant_ecpay/commits/master
|
|
42
|
+
[0.1.2]: https://rubygems.org/gems/active_merchant_ecpay/versions/0.1.2
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
## 發版規則(Ruby gem)
|
|
4
|
+
|
|
5
|
+
- 這個 gem(`active_merchant_ecpay`,gemspec:`active_merchant_ecpay.gemspec`)在 master 收到「新版本號」時,由 GitHub Actions(`.github/workflows/publish.yml`)自動發佈到 rubygems.org(Trusted Publishing,不使用 API key)。
|
|
6
|
+
- **每一個 PR 都必須跳版號**(改 `lib/active_merchant_ecpay/version.rb`),除非這個 PR 只改文件、CI 或 CLAUDE.md 且明確不需要發版。沒跳版號的 PR 合進 master 後不會發佈。
|
|
7
|
+
- 跳版規則(Semantic Versioning):修 bug 跳 patch(x.y.Z);新增相容功能跳 minor(x.Y.0);不相容變更跳 major(X.0.0)。
|
|
8
|
+
- 版號只改在 PR 裡。AI 帳號只能開 branch 與 PR,不得合併到 master;只有真人帳號可以合併。合併就等於批准發佈。
|
|
9
|
+
- 不得為了讓測試通過而改變程式原本的行為。
|
|
10
|
+
|
|
11
|
+
## 文件與更新紀錄(README / CHANGELOG)
|
|
12
|
+
|
|
13
|
+
- **每一個 PR 都必須同步更新文件**:
|
|
14
|
+
- 只要行為、用法、設定、相依套件或支援的 Ruby / Rails 版本有變,就要更新 `README.md`。
|
|
15
|
+
- 一律要在 `CHANGELOG.md` 新增一筆條目([Keep a Changelog](https://keepachangelog.com/zh-TW/1.1.0/) 格式,分類用 Added / Changed / Deprecated / Removed / Fixed / Security)。
|
|
16
|
+
- `CHANGELOG.md` 的寫法:
|
|
17
|
+
- 沒有跳版號的 PR:寫在最上方的 `## [Unreleased]` 底下。
|
|
18
|
+
- 有跳版號的 PR:把條目寫在新的版本章節 `## [x.y.z] - YYYY-MM-DD`(日期為合併日),並同步更新檔尾的版本比較連結。
|
|
19
|
+
- 版本號必須與 rubygems.org 上實際發佈的版本一致,不得寫還沒發佈的版本。
|
|
20
|
+
- 只改文件、CI 或 CLAUDE.md 的 PR 不需要跳版號,但仍要在 `CHANGELOG.md` 的 `Unreleased` 補一筆。
|
data/README.md
CHANGED
|
@@ -1,35 +1,67 @@
|
|
|
1
1
|
# ActiveMerchantEcpay
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Now it supports:
|
|
5
|
-
- Credit card(信用卡)
|
|
6
|
-
- ATM(虛擬ATM)
|
|
7
|
-
- BARCODE(超商條碼).
|
|
3
|
+
[ActiveMerchant](https://github.com/activemerchant/active_merchant) / [OffsitePayments](https://github.com/activemerchant/offsite_payments) integration for **ECPay (綠界科技 / 歐付寶)** AIO checkout in Taiwan, for Rails. It lets a Rails app:
|
|
8
4
|
|
|
9
|
-
|
|
5
|
+
- render the hidden-field form that sends a customer to the ECPay payment page (including the `CheckMacValue` signature), and
|
|
6
|
+
- parse and verify the server notification (`ReturnURL`) ECPay posts back.
|
|
7
|
+
|
|
8
|
+
Payment methods supported by the helper constants: credit card (`Credit`), virtual ATM (`ATM`), convenience store code (`CVS`), barcode (`BARCODE`) and `Alipay`.
|
|
9
|
+
|
|
10
|
+
The gem is published on [RubyGems](https://rubygems.org/gems/active_merchant_ecpay). See [CHANGELOG.md](CHANGELOG.md) for what changed in each version.
|
|
11
|
+
|
|
12
|
+
## Requirements
|
|
13
|
+
|
|
14
|
+
| | Supported |
|
|
15
|
+
| --- | --- |
|
|
16
|
+
| Ruby | 3.0, 3.1, 3.2, 3.3, 3.4 |
|
|
17
|
+
| Rails (`actionview` / `activesupport`) | 7.0, 7.1, 7.2, 8.0, 8.1 |
|
|
18
|
+
|
|
19
|
+
Rails 7.2 needs Ruby >= 3.1, and Rails 8.0 / 8.1 need Ruby >= 3.2. These are exactly the combinations the CI matrix (`.github/workflows/test.yml`) runs. Other runtime dependencies: `activemerchant ~> 1.50`, `offsite_payments ~> 2`, `money`.
|
|
10
20
|
|
|
11
21
|
## Installation
|
|
12
22
|
|
|
13
|
-
Add this line to your application's Gemfile
|
|
23
|
+
Add this line to your application's `Gemfile`:
|
|
14
24
|
|
|
15
25
|
```ruby
|
|
16
|
-
gem 'active_merchant_ecpay'
|
|
26
|
+
gem 'active_merchant_ecpay', '>= 0.2.0'
|
|
17
27
|
```
|
|
18
28
|
|
|
19
|
-
|
|
29
|
+
Then run:
|
|
20
30
|
|
|
21
|
-
|
|
31
|
+
```sh
|
|
32
|
+
bundle install
|
|
33
|
+
```
|
|
22
34
|
|
|
23
|
-
|
|
35
|
+
> Support for Rails 7+ / Ruby 3+ is released as **0.2.0**. If 0.2.0 is not yet visible on RubyGems (check the [CHANGELOG](CHANGELOG.md); 0.1.2 is the last release for older Rails), use the Git source instead:
|
|
36
|
+
> `gem 'active_merchant_ecpay', github: 'superlanding/active_merchant_ecpay'`.
|
|
24
37
|
|
|
25
|
-
|
|
38
|
+
## Configuration
|
|
26
39
|
|
|
27
|
-
|
|
40
|
+
Get your merchant credentials from ECPay (the [API spec](https://developers.ecpay.com.tw/) describes every parameter). Then create an initializer, e.g. `config/initializers/ecpay.rb`:
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
OffsitePayments::Integrations::Ecpay.setup do |ecpay|
|
|
44
|
+
if Rails.env.production?
|
|
45
|
+
ecpay.merchant_id = Rails.application.credentials.dig(:ecpay, :merchant_id)
|
|
46
|
+
ecpay.hash_key = Rails.application.credentials.dig(:ecpay, :hash_key)
|
|
47
|
+
ecpay.hash_iv = Rails.application.credentials.dig(:ecpay, :hash_iv)
|
|
48
|
+
else
|
|
49
|
+
# ECPay's public stage (test) account
|
|
50
|
+
ecpay.merchant_id = '2000132'
|
|
51
|
+
ecpay.hash_key = '5294y06JbISpM5x9'
|
|
52
|
+
ecpay.hash_iv = 'v77hoKGq4kWxNNIS'
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Choose the environment. The gateway URL depends on `ActiveMerchant::Billing::Base.mode`:
|
|
28
58
|
|
|
29
|
-
|
|
30
|
-
|
|
59
|
+
| mode | URL |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| `:production` | `https://payment.ecpay.com.tw/Cashier/AioCheckOut/V5` |
|
|
62
|
+
| `:development` / `:test` | `https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5` (stage) |
|
|
31
63
|
|
|
32
|
-
```
|
|
64
|
+
```ruby
|
|
33
65
|
# config/environments/development.rb
|
|
34
66
|
config.after_initialize do
|
|
35
67
|
ActiveMerchant::Billing::Base.mode = :development
|
|
@@ -41,55 +73,99 @@ config.after_initialize do
|
|
|
41
73
|
end
|
|
42
74
|
```
|
|
43
75
|
|
|
44
|
-
|
|
45
|
-
# initializers/ecpay.rb
|
|
46
|
-
OffsitePayments::Integrations::Ecpay.setup do |ecpay|
|
|
47
|
-
if Rails.env.development?
|
|
48
|
-
# default setting for stage test
|
|
49
|
-
ecpay.merchant_id = '2000132'
|
|
50
|
-
ecpay.hash_key = '5294y06JbISpM5x9'
|
|
51
|
-
ecpay.hash_iv = 'v77hoKGq4kWxNNIS'
|
|
52
|
-
else
|
|
53
|
-
# change to yours
|
|
54
|
-
ecpay.merchant_id = '23466XX'
|
|
55
|
-
ecpay.hash_key = 'adfasdsfgseweqwg'
|
|
56
|
-
ecpay.hash_iv = '15y3ersee34yasdf'
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
```
|
|
76
|
+
## Usage
|
|
60
77
|
|
|
61
|
-
|
|
78
|
+
### 1. Send the customer to the payment page
|
|
62
79
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
80
|
+
`payment_service_for` is available in views. Always call `service.encrypted_data` last; it computes `CheckMacValue` from every field set so far (MD5, ECPay's .NET-style URL encoding).
|
|
81
|
+
|
|
82
|
+
```erb
|
|
83
|
+
<% payment_service_for @order.id,
|
|
84
|
+
@order.user.email,
|
|
85
|
+
service: :ecpay,
|
|
86
|
+
html: { method: :post } do |service| %>
|
|
87
|
+
<% service.merchant_trade_no "#{@order.id}T#{Time.current.to_i}" %> <%# unique, alphanumeric, max 20 chars %>
|
|
88
|
+
<% service.merchant_trade_date @order.created_at %> <%# formatted as yyyy/MM/dd HH:mm:ss %>
|
|
70
89
|
<% service.total_amount @order.total.to_i %>
|
|
71
|
-
<% service.description
|
|
72
|
-
<% service.item_name
|
|
90
|
+
<% service.description 'Order description' %>
|
|
91
|
+
<% service.item_name 'Item name' %>
|
|
73
92
|
<% service.choose_payment OffsitePayments::Integrations::Ecpay::PAYMENT_ATM %>
|
|
74
|
-
<% service.return_url
|
|
75
|
-
<% service.notify_url
|
|
93
|
+
<% service.return_url root_url %> <%# ClientBackURL: button on the ECPay page back to your site %>
|
|
94
|
+
<% service.notify_url ecpay_notify_url %> <%# ReturnURL: server-to-server payment result %>
|
|
76
95
|
<% service.encrypted_data %>
|
|
77
96
|
<%= submit_tag 'Buy!' %>
|
|
78
97
|
<% end %>
|
|
79
98
|
```
|
|
80
99
|
|
|
100
|
+
The rendered `<form method="post">` points at the gateway URL above, with hidden inputs `MerchantID`, `PaymentType` (`aio`), `MerchantTradeNo`, `MerchantTradeDate`, `TotalAmount`, `TradeDesc`, `ItemName`, `ChoosePayment`, `ClientBackURL`, `ReturnURL`, `CheckMacValue`.
|
|
101
|
+
|
|
102
|
+
Payment method constants: `PAYMENT_CREDIT_CARD`, `PAYMENT_ATM`, `PAYMENT_CVS`, `PAYMENT_ALIPAY`, `PAYMENT_BARCODE`; sub-payment constants `SUBPAYMENT_ATM_*` (`TAISHIN`, `ESUN`, `HUANAN`, `BOT`, `FUBON`, `CHINATRUST`, `FIRST`) and `SUBPAYMENT_CVS_*` (`CVS`, `OK`, `FAMILY`, `HILIFE`, `IBON`), used with `service.choose_sub_payment`.
|
|
103
|
+
|
|
104
|
+
Other field setters (snake_case → ECPay parameter): `merchant_id` / `account` → `MerchantID`, `merchant_trade_no` / `order` → `MerchantTradeNo`, `total_amount` / `amount` → `TotalAmount`, `notify_url` → `ReturnURL`, `client_back_url` / `return_url` → `ClientBackURL`, `redirect_url` → `OrderResultURL`, `payment_info_url` → `PaymentInfoURL`, `client_redirect_url` / `payment_redirect_url` → `ClientRedirectURL`, `item_url`, `remark`, `need_extra_paid_info`, `devise_source`, `ignore_payment`, `platform_id`, `invoice_mark`, `hold_trade_amt`, `encrypt_type`, `expire_date` (ATM), `store_expire_date`, `desc_1` … `desc_4` (CVS / BARCODE), and the Alipay fields `alipay_item_name`, `alipay_item_counts`, `alipay_item_price`, `email`, `phone_no`, `uder_name` (sic), `expire_time`.
|
|
105
|
+
|
|
106
|
+
To use a different HashKey / HashIV for one form (for example for multiple merchants), call `service.hash_key '...'` and `service.hash_iv '...'` before `service.encrypted_data`.
|
|
107
|
+
|
|
108
|
+
### 2. Handle the notification
|
|
109
|
+
|
|
110
|
+
Point `notify_url` at a controller action, skip CSRF verification for it, and verify the signature before trusting the data:
|
|
111
|
+
|
|
112
|
+
```ruby
|
|
113
|
+
class EcpayController < ApplicationController
|
|
114
|
+
skip_before_action :verify_authenticity_token, only: :notify
|
|
115
|
+
|
|
116
|
+
def notify
|
|
117
|
+
notification = OffsitePayments::Integrations::Ecpay.notification(request.raw_post)
|
|
118
|
+
|
|
119
|
+
if notification.checksum_ok? && notification.complete?
|
|
120
|
+
order = Order.find_by!(id: notification.merchant_trade_no.split('T').first)
|
|
121
|
+
# notification.trade_no, notification.trade_amt, notification.payment_type, notification.payment_date ...
|
|
122
|
+
order.mark_as_paid!(trade_no: notification.trade_no) if notification.status
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
render plain: '1|OK' # ECPay expects "1|OK" as the response body
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Available helpers on the notification:
|
|
131
|
+
|
|
132
|
+
- `checksum_ok?` / `acknowledge` — verifies `CheckMacValue` with your `HashKey` / `HashIV`. ECPay has no remote verification, so this is the only authenticity check; **always call it**.
|
|
133
|
+
- `status` — `true` when `RtnCode == '1'` (paid). `complete?` — also `true` for the "number issued" codes: `2` (ATM virtual account issued), `10100073` (CVS / BARCODE code issued) and `800` (cash-on-delivery order created). Use `status` to know whether money was actually received.
|
|
134
|
+
- Readers: `rtn_code`, `rtn_msg`, `merchant_id`, `merchant_trade_no` (alias `item_id`), `trade_no` (alias `transaction_id`), `trade_amt`, `gross` (`Money` in TWD), `payment_date`, `payment_type`, `payment_type_charge_fee`, `trade_date`, `simulate_paid`, `check_mac_value`; ATM: `bank_code`, `v_account`, `expire_date`; credit card: `card4no`; CVS: `payment_no`; BARCODE: `barcode1`, `barcode2`, `barcode3`.
|
|
135
|
+
- To verify with a per-merchant key, set `notification.hash_key = '...'` and `notification.hash_iv = '...'` before `checksum_ok?`.
|
|
136
|
+
|
|
137
|
+
### Known limitations
|
|
138
|
+
|
|
139
|
+
- `Helper.url_encode` does not yet match ECPay's encoding for `<`, newline, carriage return and `&` inside field values (see the TODO in `helper.rb`); avoid them in `description` / `item_name`.
|
|
140
|
+
- Setting `OffsitePayments::Integrations::Ecpay.debug = true` calls `binding.pry` inside `encrypted_data` (needs the `pry` gem); never enable it in production.
|
|
141
|
+
|
|
81
142
|
## Development
|
|
82
143
|
|
|
83
|
-
|
|
144
|
+
```sh
|
|
145
|
+
git clone https://github.com/superlanding/active_merchant_ecpay.git
|
|
146
|
+
cd active_merchant_ecpay
|
|
147
|
+
BUNDLE_GEMFILE=gemfiles/rails_8.1.gemfile bundle install
|
|
148
|
+
BUNDLE_GEMFILE=gemfiles/rails_8.1.gemfile bundle exec rake t # alias of `rake spec`
|
|
149
|
+
```
|
|
84
150
|
|
|
85
|
-
|
|
151
|
+
Pick any gemfile in `gemfiles/` (`rails_7.0` … `rails_8.1`) that matches your Ruby version. The specs are RSpec, live in `spec/`, and block all network access (any `Net::HTTP` connection raises). Set `COVERAGE=1` to run SimpleCov.
|
|
86
152
|
|
|
87
|
-
|
|
153
|
+
CI (`.github/workflows/test.yml`) runs the whole Ruby × Rails matrix for every PR and push to `master`.
|
|
88
154
|
|
|
89
|
-
|
|
155
|
+
## Releasing
|
|
90
156
|
|
|
157
|
+
Releases are automatic (RubyGems [Trusted Publishing](https://guides.rubygems.org/trusted-publishing/), no API key stored):
|
|
91
158
|
|
|
92
|
-
|
|
159
|
+
1. In your PR, bump `ActiveMerchantEcpay::VERSION` in `lib/active_merchant_ecpay/version.rb` (SemVer) and move the `## [Unreleased]` entries in `CHANGELOG.md` under a new `## [x.y.z] - YYYY-MM-DD` section.
|
|
160
|
+
2. Merge the PR into `master`.
|
|
161
|
+
3. `.github/workflows/publish.yml` sees that the version is not on rubygems.org yet, builds the gem and runs `rake release`, which publishes it and creates the `vx.y.z` git tag. If the version already exists, the workflow does nothing.
|
|
162
|
+
|
|
163
|
+
PRs that do not bump the version (docs, CI, refactors) are never published.
|
|
164
|
+
|
|
165
|
+
## Contributing
|
|
166
|
+
|
|
167
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/superlanding/active_merchant_ecpay. Every pull request must also update this README (when behaviour, usage or requirements change) and add an entry to `CHANGELOG.md`; see `CLAUDE.md`.
|
|
93
168
|
|
|
94
|
-
|
|
169
|
+
## License
|
|
95
170
|
|
|
171
|
+
The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
|
data/Rakefile
CHANGED
|
@@ -14,6 +14,8 @@ Gem::Specification.new do |spec|
|
|
|
14
14
|
spec.homepage = "https://github.com/superlanding/active_merchant_ecpay"
|
|
15
15
|
spec.license = "MIT"
|
|
16
16
|
|
|
17
|
+
spec.required_ruby_version = ">= 3.0"
|
|
18
|
+
|
|
17
19
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
18
20
|
spec.bindir = "exe"
|
|
19
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
@@ -23,11 +25,12 @@ Gem::Specification.new do |spec|
|
|
|
23
25
|
spec.add_dependency 'money'
|
|
24
26
|
spec.add_dependency 'offsite_payments', '~> 2'
|
|
25
27
|
|
|
26
|
-
spec.
|
|
27
|
-
spec.
|
|
28
|
+
spec.add_dependency 'actionview', '>= 7.0', '< 8.2'
|
|
29
|
+
spec.add_dependency 'activesupport', '>= 7.0', '< 8.2'
|
|
30
|
+
|
|
31
|
+
spec.add_development_dependency "bundler", ">= 2.0"
|
|
32
|
+
spec.add_development_dependency "rake", ">= 13"
|
|
28
33
|
spec.add_development_dependency "rspec", "~> 3.0"
|
|
29
|
-
spec.add_development_dependency('mocha', '~> 0.13.0')
|
|
30
|
-
spec.add_development_dependency('rails', '>= 2.3.14')
|
|
31
34
|
spec.add_development_dependency('pry')
|
|
32
35
|
spec.add_development_dependency('thor')
|
|
33
36
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
source "https://rubygems.org"
|
|
3
|
+
|
|
4
|
+
gemspec path: ".."
|
|
5
|
+
|
|
6
|
+
gem "rails", "~> 7.0.0"
|
|
7
|
+
gem "rake", ">= 13"
|
|
8
|
+
gem "rspec", "~> 3.0"
|
|
9
|
+
gem "simplecov", require: false
|
|
10
|
+
|
|
11
|
+
# concurrent-ruby 1.3.5 起不再自動 require logger,Rails 7.0 / 7.1 會載入失敗
|
|
12
|
+
gem "concurrent-ruby", "< 1.3.5"
|
|
13
|
+
|
|
14
|
+
# Ruby 3.4 已不再內建這些 gem;Rails 7.0 / 7.1 沒有自行宣告,故明確列出
|
|
15
|
+
gem "logger"
|
|
16
|
+
gem "mutex_m"
|
|
17
|
+
gem "bigdecimal"
|
|
18
|
+
gem "base64"
|
|
19
|
+
gem "drb"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
source "https://rubygems.org"
|
|
3
|
+
|
|
4
|
+
gemspec path: ".."
|
|
5
|
+
|
|
6
|
+
gem "rails", "~> 7.1.0"
|
|
7
|
+
gem "rake", ">= 13"
|
|
8
|
+
gem "rspec", "~> 3.0"
|
|
9
|
+
gem "simplecov", require: false
|
|
10
|
+
|
|
11
|
+
# concurrent-ruby 1.3.5 起不再自動 require logger,Rails 7.0 / 7.1 會載入失敗
|
|
12
|
+
gem "concurrent-ruby", "< 1.3.5"
|
|
13
|
+
|
|
14
|
+
# Ruby 3.4 已不再內建這些 gem;Rails 7.0 / 7.1 沒有自行宣告,故明確列出
|
|
15
|
+
gem "logger"
|
|
16
|
+
gem "mutex_m"
|
|
17
|
+
gem "bigdecimal"
|
|
18
|
+
gem "base64"
|
|
19
|
+
gem "drb"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
source "https://rubygems.org"
|
|
3
|
+
|
|
4
|
+
gemspec path: ".."
|
|
5
|
+
|
|
6
|
+
gem "rails", "~> 7.2.0"
|
|
7
|
+
gem "rake", ">= 13"
|
|
8
|
+
gem "rspec", "~> 3.0"
|
|
9
|
+
gem "simplecov", require: false
|
|
10
|
+
|
|
11
|
+
# Ruby 3.4 已不再內建這些 gem;Rails 7.0 / 7.1 沒有自行宣告,故明確列出
|
|
12
|
+
gem "logger"
|
|
13
|
+
gem "mutex_m"
|
|
14
|
+
gem "bigdecimal"
|
|
15
|
+
gem "base64"
|
|
16
|
+
gem "drb"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
source "https://rubygems.org"
|
|
3
|
+
|
|
4
|
+
gemspec path: ".."
|
|
5
|
+
|
|
6
|
+
gem "rails", "~> 8.0.0"
|
|
7
|
+
gem "rake", ">= 13"
|
|
8
|
+
gem "rspec", "~> 3.0"
|
|
9
|
+
gem "simplecov", require: false
|
|
10
|
+
|
|
11
|
+
# Ruby 3.4 已不再內建這些 gem;Rails 7.0 / 7.1 沒有自行宣告,故明確列出
|
|
12
|
+
gem "logger"
|
|
13
|
+
gem "mutex_m"
|
|
14
|
+
gem "bigdecimal"
|
|
15
|
+
gem "base64"
|
|
16
|
+
gem "drb"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
source "https://rubygems.org"
|
|
3
|
+
|
|
4
|
+
gemspec path: ".."
|
|
5
|
+
|
|
6
|
+
gem "rails", "~> 8.1.0"
|
|
7
|
+
gem "rake", ">= 13"
|
|
8
|
+
gem "rspec", "~> 3.0"
|
|
9
|
+
gem "simplecov", require: false
|
|
10
|
+
|
|
11
|
+
# Ruby 3.4 已不再內建這些 gem;Rails 7.0 / 7.1 沒有自行宣告,故明確列出
|
|
12
|
+
gem "logger"
|
|
13
|
+
gem "mutex_m"
|
|
14
|
+
gem "bigdecimal"
|
|
15
|
+
gem "base64"
|
|
16
|
+
gem "drb"
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_merchant_ecpay
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Eddie Li
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activemerchant
|
|
@@ -53,75 +52,87 @@ dependencies:
|
|
|
53
52
|
- !ruby/object:Gem::Version
|
|
54
53
|
version: '2'
|
|
55
54
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
55
|
+
name: actionview
|
|
57
56
|
requirement: !ruby/object:Gem::Requirement
|
|
58
57
|
requirements:
|
|
59
|
-
- - "
|
|
58
|
+
- - ">="
|
|
60
59
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
62
|
-
|
|
60
|
+
version: '7.0'
|
|
61
|
+
- - "<"
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: '8.2'
|
|
64
|
+
type: :runtime
|
|
63
65
|
prerelease: false
|
|
64
66
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
67
|
requirements:
|
|
66
|
-
- - "
|
|
68
|
+
- - ">="
|
|
67
69
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
70
|
+
version: '7.0'
|
|
71
|
+
- - "<"
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '8.2'
|
|
69
74
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
75
|
+
name: activesupport
|
|
71
76
|
requirement: !ruby/object:Gem::Requirement
|
|
72
77
|
requirements:
|
|
73
|
-
- - "
|
|
78
|
+
- - ">="
|
|
74
79
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
76
|
-
|
|
80
|
+
version: '7.0'
|
|
81
|
+
- - "<"
|
|
82
|
+
- !ruby/object:Gem::Version
|
|
83
|
+
version: '8.2'
|
|
84
|
+
type: :runtime
|
|
77
85
|
prerelease: false
|
|
78
86
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
87
|
requirements:
|
|
80
|
-
- - "
|
|
88
|
+
- - ">="
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
version: '7.0'
|
|
91
|
+
- - "<"
|
|
81
92
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
93
|
+
version: '8.2'
|
|
83
94
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
95
|
+
name: bundler
|
|
85
96
|
requirement: !ruby/object:Gem::Requirement
|
|
86
97
|
requirements:
|
|
87
|
-
- - "
|
|
98
|
+
- - ">="
|
|
88
99
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '
|
|
100
|
+
version: '2.0'
|
|
90
101
|
type: :development
|
|
91
102
|
prerelease: false
|
|
92
103
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
104
|
requirements:
|
|
94
|
-
- - "
|
|
105
|
+
- - ">="
|
|
95
106
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '
|
|
107
|
+
version: '2.0'
|
|
97
108
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name:
|
|
109
|
+
name: rake
|
|
99
110
|
requirement: !ruby/object:Gem::Requirement
|
|
100
111
|
requirements:
|
|
101
|
-
- - "
|
|
112
|
+
- - ">="
|
|
102
113
|
- !ruby/object:Gem::Version
|
|
103
|
-
version:
|
|
114
|
+
version: '13'
|
|
104
115
|
type: :development
|
|
105
116
|
prerelease: false
|
|
106
117
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
118
|
requirements:
|
|
108
|
-
- - "
|
|
119
|
+
- - ">="
|
|
109
120
|
- !ruby/object:Gem::Version
|
|
110
|
-
version:
|
|
121
|
+
version: '13'
|
|
111
122
|
- !ruby/object:Gem::Dependency
|
|
112
|
-
name:
|
|
123
|
+
name: rspec
|
|
113
124
|
requirement: !ruby/object:Gem::Requirement
|
|
114
125
|
requirements:
|
|
115
|
-
- - "
|
|
126
|
+
- - "~>"
|
|
116
127
|
- !ruby/object:Gem::Version
|
|
117
|
-
version:
|
|
128
|
+
version: '3.0'
|
|
118
129
|
type: :development
|
|
119
130
|
prerelease: false
|
|
120
131
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
132
|
requirements:
|
|
122
|
-
- - "
|
|
133
|
+
- - "~>"
|
|
123
134
|
- !ruby/object:Gem::Version
|
|
124
|
-
version:
|
|
135
|
+
version: '3.0'
|
|
125
136
|
- !ruby/object:Gem::Dependency
|
|
126
137
|
name: pry
|
|
127
138
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -157,9 +168,13 @@ executables: []
|
|
|
157
168
|
extensions: []
|
|
158
169
|
extra_rdoc_files: []
|
|
159
170
|
files:
|
|
171
|
+
- ".github/workflows/publish.yml"
|
|
172
|
+
- ".github/workflows/test.yml"
|
|
160
173
|
- ".gitignore"
|
|
161
174
|
- ".rspec"
|
|
162
175
|
- ".travis.yml"
|
|
176
|
+
- CHANGELOG.md
|
|
177
|
+
- CLAUDE.md
|
|
163
178
|
- Gemfile
|
|
164
179
|
- LICENSE.txt
|
|
165
180
|
- README.md
|
|
@@ -167,6 +182,11 @@ files:
|
|
|
167
182
|
- active_merchant_ecpay.gemspec
|
|
168
183
|
- bin/console
|
|
169
184
|
- bin/setup
|
|
185
|
+
- gemfiles/rails_7.0.gemfile
|
|
186
|
+
- gemfiles/rails_7.1.gemfile
|
|
187
|
+
- gemfiles/rails_7.2.gemfile
|
|
188
|
+
- gemfiles/rails_8.0.gemfile
|
|
189
|
+
- gemfiles/rails_8.1.gemfile
|
|
170
190
|
- lib/active_merchant_ecpay.rb
|
|
171
191
|
- lib/active_merchant_ecpay/version.rb
|
|
172
192
|
- lib/offsite_payments/integrations/ecpay.rb
|
|
@@ -176,7 +196,6 @@ homepage: https://github.com/superlanding/active_merchant_ecpay
|
|
|
176
196
|
licenses:
|
|
177
197
|
- MIT
|
|
178
198
|
metadata: {}
|
|
179
|
-
post_install_message:
|
|
180
199
|
rdoc_options: []
|
|
181
200
|
require_paths:
|
|
182
201
|
- lib
|
|
@@ -184,16 +203,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
184
203
|
requirements:
|
|
185
204
|
- - ">="
|
|
186
205
|
- !ruby/object:Gem::Version
|
|
187
|
-
version: '0'
|
|
206
|
+
version: '3.0'
|
|
188
207
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
189
208
|
requirements:
|
|
190
209
|
- - ">="
|
|
191
210
|
- !ruby/object:Gem::Version
|
|
192
211
|
version: '0'
|
|
193
212
|
requirements: []
|
|
194
|
-
|
|
195
|
-
rubygems_version: 2.4.8
|
|
196
|
-
signing_key:
|
|
213
|
+
rubygems_version: 3.6.9
|
|
197
214
|
specification_version: 4
|
|
198
215
|
summary: ActiveMerchant x Ecpay (綠界科技)
|
|
199
216
|
test_files: []
|