allinpay_cnp 0.1.5 → 0.1.7

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: eeeda5ea5ef28fb25989946746361e94d696c5c550175502a5b21758a04892dc
4
- data.tar.gz: 034452c2f863fcc6d66ceb4d925d386a1644e1a93a3c5c61fcaeda02170f90fb
3
+ metadata.gz: ac650967bd79647830a80efd1d725613148afcc828675284ad3ed8142be5df3a
4
+ data.tar.gz: 218cb69cf48768732567cf4bf49f0e5dd6ac9f4424e06ab93a2e83e180016431
5
5
  SHA512:
6
- metadata.gz: c07e269b643265cee50a9db7a446ea6ae44d85ec1e5bcad13ab647e7ac523f4a9cc3c38f2975ac64fccb9e51af61ef573988085864be7737fa31ae52c471d600
7
- data.tar.gz: 01e7e53b849f4ee10f39618372228e9f52d961739f9dbdfce34dcdf82f9f554794cfbaf97a1d24d6e8e5856ba0df28aa8e3c77e5cdff44e4629ecbf310dc5504
6
+ metadata.gz: fe077759b23abafaf7c567a2f2cf45a0c6f14fe2ec8162196604a5b441f037b09c422bec6ead4f67d0c5d922fb07c921ef3ba7227f7cca9c57e09eaca0f58c68
7
+ data.tar.gz: adfb37bdd7f78350c362484ab1b1a062aade3e6aa29342f8484d17039e1f98be67c3f1aabb31a0bd73db65c2fa6628af361393c82cc61a2a2e1ce56c918617d6
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  ### Gemfile
8
8
 
9
9
  ```ruby
10
- gem 'allinpay_cnp', git: 'https://github.com/your-org/allinpay_cnp'
10
+ gem 'allinpay_cnp', '~> 0.1.7'
11
11
  ```
12
12
 
13
13
  ### 本地安装
@@ -15,7 +15,7 @@ gem 'allinpay_cnp', git: 'https://github.com/your-org/allinpay_cnp'
15
15
  ```bash
16
16
  cd allinpay_cnp
17
17
  gem build allinpay_cnp.gemspec
18
- gem install allinpay_cnp-0.1.0.gem
18
+ gem install allinpay_cnp-0.1.7.gem
19
19
  ```
20
20
 
21
21
  ## 配置
@@ -29,6 +29,7 @@ AllinpayCnp.configure do |config|
29
29
  config.merchant_id = Rails.application.credentials.dig(:allinpay, :merchant_id)
30
30
  config.private_key = Rails.application.credentials.dig(:allinpay, :private_key)
31
31
  config.public_key = Rails.application.credentials.dig(:allinpay, :public_key)
32
+ config.inst_no = Rails.application.credentials.dig(:allinpay, :inst_no)
32
33
  config.environment = Rails.env.production? ? :production : :test
33
34
  config.timeout = 30
34
35
  config.logger = Rails.logger
@@ -44,7 +45,8 @@ AllinpayCnp.configure do |config|
44
45
  config.merchant_id = '086310030670001'
45
46
  config.private_key = File.read('private_key.pem')
46
47
  config.public_key = File.read('public_key.pem')
47
- config.environment = :test # :test 或 :production
48
+ config.inst_no = '00000001' # 机构模式下必填,直连商户模式不填
49
+ config.environment = :test # :test 或 :production
48
50
  config.timeout = 30
49
51
  config.logger = Logger.new($stdout)
50
52
  end
@@ -54,13 +56,24 @@ end
54
56
 
55
57
  | 配置项 | 类型 | 必填 | 说明 |
56
58
  |--------|------|------|------|
57
- | `merchant_id` | String | 是 | 商户号 |
58
- | `private_key` | String | 是 | 商户私钥 (PEM 格式) |
59
- | `public_key` | String | 否 | CNP 公钥,用于验证回调签名 |
59
+ | `merchant_id` | String | 条件必填 | 商户号。若每次调用时都传入 `merchant_no`,可不在全局配置 |
60
+ | `private_key` | String | 条件必填 | 商户私钥 (PEM 格式),用于请求签名。若每次调用时都传入 `private_key`,可不在全局配置 |
61
+ | `public_key` | String | 否 | 系统公钥 (PEM 格式),用于验证回调/应答签名。亦可在调用时通过 `public_key` / `verify_callback(public_key:)` 传入 |
62
+ | `inst_no` | String | 否 | 机构号,机构模式下必填,直连商户模式留空 |
60
63
  | `environment` | Symbol | 否 | `:test` (默认) 或 `:production` |
61
64
  | `timeout` | Integer | 否 | 请求超时时间,默认 30 秒 |
62
65
  | `logger` | Logger | 否 | 日志对象 |
63
66
 
67
+ > 多商户模式下可以不在全局配置 `merchant_id` / `private_key`,而是在每次调用时按商户传入。详见 [多商户模式](#多商户模式-per-call-credentials)。
68
+
69
+ ### 密钥说明
70
+
71
+ | 密钥 | 用途 | 对应配置 |
72
+ |------|------|----------|
73
+ | 商户私钥 | 请求时计算签名 | `config.private_key` |
74
+ | 系统公钥 | 接收应答/异步通知时验签 | `config.public_key` |
75
+ | 商户公钥 | 上传至通联后台,通联用来验证你的请求签名 | 不需要配置到代码中 |
76
+
64
77
  ## 使用方法
65
78
 
66
79
  ### 获取客户端
@@ -83,7 +96,10 @@ response = client.unified_pay(
83
96
  return_url: 'https://your-domain.com/payments/complete'
84
97
  },
85
98
  email: 'customer@example.com',
86
- language: 'zh-hant', # 可选: zh-hant, zh-hans, en
99
+ language: 'zh-CN', # 可选,收银台语言,见下方「收银台语言」;无法识别时回退 en
100
+ product_info: [ # 商品信息,可选,会以 JSON 字符串形式发送
101
+ { sku: 'SKU001', productName: 'Test Product', price: '100.00', quantity: '1' }
102
+ ],
87
103
  shipping: {
88
104
  first_name: 'Peter',
89
105
  last_name: 'Zhang',
@@ -111,10 +127,34 @@ else
111
127
  end
112
128
  ```
113
129
 
130
+ #### 收银台语言 (language)
131
+
132
+ 通联只接受下面 8 个语言码。`language` 会先经过 `AllinpayCnp::Language.resolve`
133
+ 归一化,所以可以直接传常见的 locale 写法(大小写、`_`/`-` 分隔都行),
134
+ 识别不出来的(俄语、泰语、德语……)以及不传时,统一回退英文。
135
+
136
+ | 传入 locale | 发送的 language | 语言 |
137
+ | --- | --- | --- |
138
+ | `zh` / `zh-CN` / `zh-Hans` | `zh` | 简体中文 |
139
+ | `zh-TW` / `zh-HK` / `zh-MO` / `zh-hant` | `zh-hant` | 繁体中文 |
140
+ | `en` | `en` | 英语 |
141
+ | `ja` / `jp` | `ja` | 日语 |
142
+ | `ko` / `kr` | `kr` | 韩语(注意通联写作 `kr`) |
143
+ | `fr` | `fr` | 法语 |
144
+ | `es` | `es` | 西班牙语 |
145
+ | `ar` | `ar` | 阿拉伯语 |
146
+ | 其他 / 不传 | `en` | 英语(默认) |
147
+
148
+ ```ruby
149
+ AllinpayCnp::Language.resolve('zh-CN') # => "zh"
150
+ AllinpayCnp::Language.resolve('ko') # => "kr"
151
+ AllinpayCnp::Language.resolve('ru') # => "en"
152
+ ```
153
+
114
154
  ### 查询订单 (Query)
115
155
 
116
156
  ```ruby
117
- response = client.query('ORIGINAL_ORDER_123')
157
+ response = client.query(ori_access_order_id: 'ORIGINAL_ORDER_123')
118
158
 
119
159
  if response.success?
120
160
  puts "状态: #{response.status}" # SUCCESS, FAIL, PROCESSING
@@ -168,6 +208,33 @@ class WebhooksController < ApplicationController
168
208
  end
169
209
  ```
170
210
 
211
+ ## 多商户模式 (Per-call credentials)
212
+
213
+ 如果你的应用需要为多个商户代发请求 (商户模式 / 非机构模式),每个商户拥有独立的密钥对。可在调用时传入 `private_key` / `public_key` / `merchant_no`,会覆盖全局配置:
214
+
215
+ ```ruby
216
+ response = client.unified_pay(
217
+ access_order_id: "ORDER_#{Time.now.to_i}",
218
+ amount: '100.00',
219
+ currency: 'HKD',
220
+ urls: { notify_url: '...', return_url: '...' },
221
+ merchant_no: merchant.allinpay_id,
222
+ private_key: merchant.allinpay_private_key,
223
+ public_key: merchant.allinpay_public_key
224
+ )
225
+
226
+ # query / refund 同样支持
227
+ client.query(ori_access_order_id: 'ORDER_123',
228
+ merchant_no: merchant.allinpay_id,
229
+ private_key: merchant.allinpay_private_key,
230
+ public_key: merchant.allinpay_public_key)
231
+
232
+ # 回调验签时使用对应商户的 public_key
233
+ client.verify_callback(params, public_key: merchant.allinpay_public_key)
234
+ ```
235
+
236
+ 未传入时会回退到 `AllinpayCnp.configure` 中的全局配置,因此单商户用法完全向后兼容。
237
+
171
238
  ## Response 对象
172
239
 
173
240
  所有 API 方法都返回 `Response` 对象:
@@ -211,9 +278,9 @@ lib/
211
278
  └── allinpay_cnp/
212
279
  ├── version.rb # 版本号
213
280
  ├── config.rb # 配置类
281
+ ├── language.rb # 收银台语言归一化
214
282
  ├── signature.rb # RSA2 签名
215
283
  ├── request.rb # HTTP 请求
216
284
  ├── response.rb # 响应封装
217
285
  └── client.rb # API 客户端
218
286
  ```
219
-
@@ -11,7 +11,9 @@ module AllinpayCnp
11
11
  amount = opts.fetch(:amount)
12
12
  currency = opts.fetch(:currency)
13
13
  urls = opts.fetch(:urls)
14
- options = opts.except(:access_order_id, :amount, :currency, :urls)
14
+ private_key = opts[:private_key]
15
+ public_key = opts[:public_key]
16
+ options = opts.except(:access_order_id, :amount, :currency, :urls, :private_key, :public_key)
15
17
 
16
18
  params = build_unified_pay_params(
17
19
  access_order_id: access_order_id,
@@ -21,7 +23,7 @@ module AllinpayCnp
21
23
  **options
22
24
  )
23
25
 
24
- request.post(:unified_pay, params)
26
+ request.post(:unified_pay, params, private_key: private_key, public_key: public_key)
25
27
  end
26
28
 
27
29
  def query(hash_or_opts = nil, **kwargs)
@@ -29,6 +31,8 @@ module AllinpayCnp
29
31
 
30
32
  merchant_no = opts.fetch(:merchant_no, config.merchant_id)
31
33
  ori_access_order_id = opts.fetch(:ori_access_order_id)
34
+ private_key = opts[:private_key]
35
+ public_key = opts[:public_key]
32
36
 
33
37
  params = {
34
38
  version: VERSION,
@@ -38,16 +42,18 @@ module AllinpayCnp
38
42
  accessOrderId: generate_order_id,
39
43
  oriAccessOrderId: ori_access_order_id
40
44
  }.compact
41
- request.post(:quickpay, params)
45
+ request.post(:quickpay, params, private_key: private_key, public_key: public_key)
42
46
  end
43
47
 
44
48
  def refund(hash_or_opts = nil, **kwargs)
45
49
  opts = (hash_or_opts || {}).merge(kwargs).transform_keys(&:to_sym)
46
50
 
47
- merchant_no = opts.fetch(:merchant_no)
51
+ merchant_no = opts.fetch(:merchant_no, config.merchant_id)
48
52
  ori_access_order_id = opts.fetch(:ori_access_order_id)
49
53
  refund_amount = opts.fetch(:refund_amount)
50
54
  access_order_id = opts.fetch(:access_order_id, generate_order_id)
55
+ private_key = opts[:private_key]
56
+ public_key = opts[:public_key]
51
57
 
52
58
  params = {
53
59
  version: VERSION,
@@ -59,19 +65,20 @@ module AllinpayCnp
59
65
  refundAmount: refund_amount.to_s,
60
66
  notifyUrl: opts.fetch(:notify_url, nil)
61
67
  }.reject { |_, v| v.nil? }
62
- request.post(:quickpay, params)
68
+ request.post(:quickpay, params, private_key: private_key, public_key: public_key)
63
69
  end
64
70
 
65
- def verify_callback(params)
66
- return false unless config.public_key
71
+ def verify_callback(params, public_key: nil)
72
+ key = public_key || config.public_key
73
+ return false unless key
67
74
 
68
- Signature.verify(params, config.public_key)
75
+ Signature.verify(params, key)
69
76
  end
70
77
 
71
78
  private
72
79
 
73
80
  def generate_order_id
74
- Time.now.to_i.to_s
81
+ (Time.now.to_f * 1000).to_i.to_s
75
82
  end
76
83
 
77
84
  def inst_no_param
@@ -117,7 +124,7 @@ module AllinpayCnp
117
124
 
118
125
  def build_base_option_params(options)
119
126
  {
120
- language: options[:language] || 'zh-hant',
127
+ language: Language.resolve(options[:language]),
121
128
  email: options[:email],
122
129
  productInfo: options[:product_info]&.to_json
123
130
  }
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AllinpayCnp
4
+ # 收银台网站语言 (`language`)。
5
+ #
6
+ # 通联只接受下面 8 个语言码,传别的会被拒绝;本模块把常见的 locale 写法
7
+ # (`zh-CN`、`zh_TW`、`ko` ...) 归一化过去,认不出来的一律回退英文。
8
+ #
9
+ # AllinpayCnp::Language.resolve('zh-CN') # => "zh"
10
+ # AllinpayCnp::Language.resolve('ko') # => "kr"
11
+ # AllinpayCnp::Language.resolve('ru') # => "en"
12
+ module Language
13
+ DEFAULT = 'en'
14
+
15
+ # 通联语言码 => 归一到该语言码的 locale。注意韩语在通联是 `kr`,不是 `ko`。
16
+ LOCALES_BY_LANGUAGE = {
17
+ 'zh' => %w[zh zh-cn zh-hans],
18
+ 'zh-hant' => %w[zh-tw zh-hant zh-hk zh-mo],
19
+ 'en' => %w[en],
20
+ 'ja' => %w[ja jp],
21
+ 'kr' => %w[ko kr],
22
+ 'fr' => %w[fr],
23
+ 'es' => %w[es],
24
+ 'ar' => %w[ar]
25
+ }.freeze
26
+
27
+ SUPPORTED = LOCALES_BY_LANGUAGE.each_with_object({}) do |(language, locales), map|
28
+ locales.each { |locale| map[locale] = language }
29
+ end.freeze
30
+
31
+ def self.resolve(locale)
32
+ SUPPORTED.fetch(normalize(locale), DEFAULT)
33
+ end
34
+
35
+ def self.normalize(locale)
36
+ locale.to_s.strip.tr('_', '-').downcase
37
+ end
38
+ private_class_method :normalize
39
+ end
40
+ end
@@ -16,13 +16,13 @@ module AllinpayCnp
16
16
  }
17
17
  }.freeze
18
18
 
19
- def post(endpoint_type, params)
20
- sign_params(params)
19
+ def post(endpoint_type, params, private_key: nil, public_key: nil)
20
+ sign_params(params, private_key)
21
21
  url = build_url(endpoint_type)
22
22
  log_request(url, params)
23
23
  response = send_post(url, params)
24
24
  log_response(response)
25
- Response.new(response, public_key: config.public_key)
25
+ Response.new(response, public_key: public_key || config.public_key)
26
26
  rescue Faraday::Error => e
27
27
  log_error(e.message)
28
28
  Response.new(nil, error: e)
@@ -34,9 +34,9 @@ module AllinpayCnp
34
34
  AllinpayCnp.config
35
35
  end
36
36
 
37
- def sign_params(params)
37
+ def sign_params(params, private_key = nil)
38
38
  params[:signType] = 'RSA2'
39
- params[:sign] = Signature.sign(params, config.private_key)
39
+ params[:sign] = Signature.sign(params, private_key || config.private_key)
40
40
  end
41
41
 
42
42
  def build_url(endpoint_type)
@@ -18,7 +18,7 @@ module AllinpayCnp
18
18
 
19
19
  sign_string = build_sign_string(params)
20
20
  rsa_verify(sign_string, signature, public_key)
21
- rescue StandardError
21
+ rescue OpenSSL::PKey::PKeyError, OpenSSL::OpenSSLError
22
22
  false
23
23
  end
24
24
 
@@ -49,7 +49,7 @@ module AllinpayCnp
49
49
  end
50
50
 
51
51
  def load_private_key(key_content)
52
- if key_content.include?('-----BEGIN')
52
+ if key_content.include?('-----BEGIN PRIVATE KEY') || key_content.include?('-----BEGIN RSA PRIVATE KEY')
53
53
  OpenSSL::PKey::RSA.new(key_content)
54
54
  else
55
55
  pem = "-----BEGIN PRIVATE KEY-----\n#{key_content}\n-----END PRIVATE KEY-----"
@@ -58,7 +58,7 @@ module AllinpayCnp
58
58
  end
59
59
 
60
60
  def load_public_key(key_content)
61
- if key_content.include?('-----BEGIN')
61
+ if key_content.include?('-----BEGIN PUBLIC KEY')
62
62
  OpenSSL::PKey::RSA.new(key_content)
63
63
  else
64
64
  pem = "-----BEGIN PUBLIC KEY-----\n#{key_content}\n-----END PUBLIC KEY-----"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AllinpayCnp
4
- VERSION = '0.1.5'
4
+ VERSION = '0.1.7'
5
5
  end
data/lib/allinpay_cnp.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative 'allinpay_cnp/version'
4
4
  require_relative 'allinpay_cnp/config'
5
+ require_relative 'allinpay_cnp/language'
5
6
  require_relative 'allinpay_cnp/signature'
6
7
  require_relative 'allinpay_cnp/response'
7
8
  require_relative 'allinpay_cnp/request'
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: allinpay_cnp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - DrinE
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-03-31 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: faraday
@@ -41,16 +40,15 @@ files:
41
40
  - lib/allinpay_cnp.rb
42
41
  - lib/allinpay_cnp/client.rb
43
42
  - lib/allinpay_cnp/config.rb
43
+ - lib/allinpay_cnp/language.rb
44
44
  - lib/allinpay_cnp/request.rb
45
45
  - lib/allinpay_cnp/response.rb
46
46
  - lib/allinpay_cnp/signature.rb
47
47
  - lib/allinpay_cnp/version.rb
48
- - lib/debug.rb
49
48
  homepage: https://github.com/CoolDrinELiu/allinpay
50
49
  licenses:
51
50
  - MIT
52
51
  metadata: {}
53
- post_install_message:
54
52
  rdoc_options: []
55
53
  require_paths:
56
54
  - lib
@@ -65,8 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
63
  - !ruby/object:Gem::Version
66
64
  version: '0'
67
65
  requirements: []
68
- rubygems_version: 3.5.9
69
- signing_key:
66
+ rubygems_version: 4.0.6
70
67
  specification_version: 4
71
68
  summary: Ruby SDK for Allinpay CNP cross-border payment gateway
72
69
  test_files: []
data/lib/debug.rb DELETED
@@ -1,86 +0,0 @@
1
- require './allinpay_cnp'
2
-
3
- AllinpayCnp.configure do |config|
4
- config.merchant_id = '086310058120045'
5
- config.private_key = <<~XXX
6
- -----BEGIN PRIVATE KEY-----
7
- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDFt99S9adbC84l
8
- LExEF4vjFHiurFNRmBVEMmVVeJQfzQbQ/6fY0s+2Vx0lHVcD5ZVdDRwbTl2LG+8S
9
- lWH6aXmvOk5j5DI9wGJEwPo2L8GH9RHbHMQu0jr9+UO97kBCjKNZKmWkbNsPrfUb
10
- HxWuKKFILaZcv4LYNsjBNvVkvRU674lJVQ+TZ8ZsPLvc5+I3anJGLbu5Bt1igqbn
11
- vpMV1seYsUnNbuDBSoYHl09CPvGRc5krmRyouwwLlXiwcJDNDudl5Uohwj2LCuiC
12
- TWfkd/Me1ty1YrAZR9a/zh+vM7dLc9aCBnic2/7JYBtPwcKKC0Zix9ODbNehLahE
13
- Nqvxm9KtAgMBAAECggEAE3lb1rj5Zd9Qy5qEXISRM6mVhWbVwgift5rbHkMFG+i+
14
- ziEQMCv7Z3NHHJu6MVkQkBy1cv8R+ZyjvInYH6j54kd05yPXyvtC8pCrVGD5x+Fc
15
- g99ed1ofk1pU0MVBsQxXHnYtkrdiEDZLGQPDx+aalBhi9Wmrgo5K0bUPEIALMkWv
16
- RIBTkRbA/SB4WatB7zmKJxkqA+YIRzAmLDgUE1qjyhE/1VG/d/aetkwGkMo+HSDU
17
- x87ERKSbgLCri80UQ9RnMtV/wp9nh0VD3b6+MVFKacfKLHBrAwT3E/8Lv4S0I/Sr
18
- I94IoxOP4gCxytps+BslNuSCd3mMp8OuxCkqg2PBhQKBgQDmC+SpWH4WU/1XO/w9
19
- C0HnV7b0mpLt4+BqN/1eHdKK29L4R0iOqRjnO9bCkWGnV8nGU0kzNk9jueK2QBdR
20
- eOnmwqFCvEaIksyG/sUcHkzCxgtUvHxhy3e9IvjKv/5y47P9w/YgIZn62X+tWsnv
21
- EzPKPfw2+ALxllkVWZsBqB3hrwKBgQDcBkoL1JRWlrPaaSzcUbyJKUQWwIm9trHj
22
- XAYzwwsNjhGuV/aefVI7priLOxWR9Djq5IuOabNQ290ve6Bu2BBrEtbIsL/0UXwq
23
- HAmWXuCFc9/MfocQ+TiE0BuUDKgsYqQU2DE+JLaxvaUv1DNw2bUgm9z3zQyJJed4
24
- ZAHrYqo0YwKBgE9GGe4hiJG5L7w395wxnOxT1cBE5A0GUfdIhA9Cx6MCTZkxN1ex
25
- /drxS/iQkM5R+j5VxQvY01LSY8XaIC77M99Jgri0mLnHnKOId/RQnLMh/BWfPl2U
26
- +BY9Tu7Paqe8v/Ha7Z309lLzUIQ0nRG91EMFSTzICnumC9zHnBreDC4RAoGBAMWl
27
- JKjh6eqqb594MSMsjVcM6awigtkXn05kYPHoeCpR/5IEVHZkjxUkm8v+ZE76+pIO
28
- gUqJqtms11ELFb/ceUsl3ijjlVssQ4Q0MWyRh9B5mYVB96SIq3uq0cs5X2yXo1tS
29
- JVH0euTJPfTsAtWRy4IiYOl8mZEtqnNcKtk+hTSPAoGAKSF7NCZU0hQwu/rf8v7v
30
- go/qdS/oYDUohs5HVLG074Eerb1Q4w/xUfSz8zIJvTg04PLWwiBO3P5hCoXUXEaR
31
- V3Dl1g4i/pGrurOQQHhH9gdPINGBb7okthIwl02QT1UxX3Ibq1OjuH27qoCRQtWJ
32
- 7oJx+aHeFOuOHjULBy+6/CU=
33
- -----END PRIVATE KEY-----
34
- XXX
35
- config.public_key = <<~PEM
36
- -----BEGIN PUBLIC KEY-----
37
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsNGWmxYl6uYA/X3k1OOY
38
- nMlLvmgJpYMvahxDLUc9CEXbaqMoMMuLbsvfR6Zf3JIeYCjjfgNVDJTsJY/HWWbp
39
- HEd4GvQAgv6wywsQ8AJqIHe3fM3B8iwS3XIxZM9fs92lU+mHuVHQdMvciQyaB3iw
40
- 3IvBBzCEgyqSFcGBrlQOGf1x7fZZKY9RH3EDxqzE+Zrs27BjE8T3sNvUCKcfWGhQ
41
- GKX80jcqLEnFBl9CIlgL4TRSksQ1U4GhOY0/4Db6UsmbTAQeG2plWgbJ0l0khJ2O
42
- DYqTtDujl4zN3tGXQ2gwCErxqBbukIFMkT+jS1lxrBeGGrvuOXTz408tDbAsJnbU
43
- YwIDAQAB
44
- -----END PUBLIC KEY-----
45
- PEM
46
- config.environment = :test
47
- config.logger = Logger.new($stdout)
48
- end
49
-
50
- client = AllinpayCnp.client
51
-
52
- # 测试创建订单
53
- response = client.unified_pay(
54
- access_order_id: "TEST_#{Time.now.to_i}",
55
- amount: '1.00',
56
- currency: 'HKD',
57
- urls: {
58
- notify_url: 'https://example.com/callback',
59
- return_url: 'https://example.com/return'
60
- },
61
- email: 'test@example.com',
62
- product_info: [
63
- {
64
- # sku: '123456789',
65
- productName: 'MacBook Pro'
66
- # price: '1.00',
67
- # quantity: '1'
68
- }
69
- ],
70
- shipping: {
71
- first_name: 'Peter',
72
- last_name: 'Zhang',
73
- address1: '123 Test Street',
74
- city: 'Hong Kong',
75
- state: 'Hong Kong',
76
- country: 'HK',
77
- zip_code: '000000',
78
- phone: '12345678'
79
- }
80
- )
81
-
82
- q = client.query('TEST_1771053407')
83
- puts "Success: #{response.success?}"
84
- puts "Result Code: #{response.result_code}"
85
- puts "Result Desc: #{response.result_desc}"
86
- puts "Payment URL: #{response.payment_url}" if response.success?