class Wechatpay::Api::V3::Client
Constants
- SCHEMA
Attributes
appid[R]
key[R]
logger[RW]
mch_id[R]
rsa_key[R]
serial_no[R]
site[RW]
Public Class Methods
new(appid, mch_id, **opts)
click to toggle source
# File lib/wechatpay/api/v3/client.rb, line 18 def initialize(appid, mch_id, **opts) @appid = appid @mch_id = mch_id @rsa_key = OpenSSL::PKey::RSA.new opts[:cert] if opts[:cert] @serial_no = opts[:cert_no] @key = opts[:key] @site = opts[:site] || 'https://api.mch.weixin.qq.com' @logger = Logger.new(STDOUT) end
Public Instance Methods
cert()
click to toggle source
# File lib/wechatpay/api/v3/client.rb, line 65 def cert Wechatpay::Api::V3::Cert.instance.load || update_certs end
connection()
click to toggle source
# File lib/wechatpay/api/v3/client.rb, line 29 def connection Faraday.new(url: @site) do |conn| conn.request :retry conn.response :logger # conn.response :raise_error conn.adapter :net_http end end
dechipher(data, nonce, auth_data)
click to toggle source
# File lib/wechatpay/api/v3/client.rb, line 119 def dechipher(data, nonce, auth_data) chipher = OpenSSL::Cipher.new 'aes-256-gcm' chipher.decrypt chipher.key = key chipher.iv = nonce chipher.padding = 0 chipher.auth_data = auth_data chipher.auth_tag = data[-16, 16] chipher end
decrypt(cipher_text, nonce, auth_data)
click to toggle source
# File lib/wechatpay/api/v3/client.rb, line 111 def decrypt(cipher_text, nonce, auth_data) raise :cipher_text_invalid if (cipher_text.try(:length) || 0) < 16 data = Base64.strict_decode64(cipher_text) dec = dechipher(data, nonce, auth_data) dec.update(data[0, data.length - 16]).tap { |s| logger.debug "DEC: #{s}" } + dec.final end
get(path, params = nil)
click to toggle source
# File lib/wechatpay/api/v3/client.rb, line 38 def get(path, params = nil) resp = connection.get(path, params) do |req| path = req.path path = [req.path, Faraday::Utils.build_query(req.params)].join('?') unless params.nil? || params.empty? req.headers['Authorization'] = authorization_header('GET', path, nil) req.headers['Accept'] = 'application/json' end handle resp end
handle(resp)
click to toggle source
# File lib/wechatpay/api/v3/client.rb, line 77 def handle(resp) logger.debug { "HANDLE RESPONSE: #{resp.inspect}" } data = resp.body raise :empty_body unless data && !data.empty? MultiJson.load data, symbolize_keys: true end
post(path, data, **headers)
click to toggle source
# File lib/wechatpay/api/v3/client.rb, line 48 def post(path, data, **headers) body = data.is_a?(Hash) ? MultiJson.dump(data) : data resp = connection.post(path, body, headers) do |req| req.headers['Authorization'] = authorization_header('POST', path, body) req.headers['Accept'] = 'application/json' end handle resp end
sign_content(content)
click to toggle source
# File lib/wechatpay/api/v3/client.rb, line 91 def sign_content(content) digest = OpenSSL::Digest::SHA256.new signed = rsa_key.sign(digest, content) Base64.strict_encode64 signed end
sign_with(body, method, path, timestamp, rnd)
click to toggle source
# File lib/wechatpay/api/v3/client.rb, line 85 def sign_with(body, method, path, timestamp, rnd) str = [method, path, timestamp, rnd, body].join("\n") + "\n" logger.debug { "Sign Content: #{str.inspect}" } sign_content(str) end
update_certs()
click to toggle source
# File lib/wechatpay/api/v3/client.rb, line 69 def update_certs certs = get('/v3/certificates')[:data] certs.map do |raw| Wechatpay::Api::V3::Cert.instance.update(raw, &method(:decrypt)) end Wechatpay::Api::V3::Cert.instance end
verify(headers, body)
click to toggle source
# File lib/wechatpay/api/v3/client.rb, line 57 def verify(headers, body) sha256 = OpenSSL::Digest::SHA256.new key = cert.certificate.public_key sign = Base64.strict_decode64(headers['Wechatpay-Signature']) data = %w[Wechatpay-Timestamp Wechatpay-Nonce].map { |k| headers[k] } key.verify sha256, sign, data.append(body).join("\n") + "\n" end