Module: UnionpayApp::Service

Defined in:
lib/unionpay_app/service.rb

Class Method Summary collapse

Class Method Details

.get_public_key_by_cert_id(cert_id) ⇒ Object

银联支付 根据证书id返回公钥



61
62
63
64
# File 'lib/unionpay_app/service.rb', line 61

def self.get_public_key_by_cert_id cert_id
	certificate = OpenSSL::X509::Certificate.new(UnionpayApp.cer) #读取cer文件
	certificate.serial.to_s == cert_id ? certificate.public_key.to_s : nil #php 返回的直接是cer文件 UnionpayApp.cer
end

.post(union_params) ⇒ Object



34
35
36
37
38
39
40
41
42
# File 'lib/unionpay_app/service.rb', line 34

def self.post union_params
	request = Typhoeus::Request.new(UnionpayApp.uri, method: :post, params: union_params[:sign], ssl_verifypeer: false, headers: {'Content-Type' =>'application/x-www-form-urlencoded'} )
  request.run
  if request.response.success?
    tn = Hash[*request.response.body.split("&").map{|a| a.gsub("==", "@@").split("=")}.flatten]['tn']
  else
    tn = ""
  end
end

.query(order_id, txnTime) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/unionpay_app/service.rb', line 66

def self.query order_id, txnTime
	union_params = {
    :version => '5.0.0',		#版本号
    :encoding => 'utf-8',		#编码方式
    :certId => UnionpayApp.cert_id,	#证书ID	
    :signMethod => '01',		#签名方法
    :txnType => '00',		#交易类型	
    :txnSubType => '00',		#交易子类
    :bizType => '000000',		#业务类型
    :accessType => '0',		#接入类型
    :channelType => '07',		#渠道类型
    :orderId => order_id,	#请修改被查询的交易的订单号
    :merId => UnionpayApp.mer_id,	#商户代码,请修改为自己的商户号
    :txnTime => txnTime,	#请修改被查询的交易的订单发送时间
	}
	data = Digest::SHA1.hexdigest(union_params.sort.map{|key, value| "#{key}=#{value}" }.join('&'))
  sign = Base64.encode64(OpenSSL::PKey::RSA.new(UnionpayApp.private_key).sign('sha1', data.force_encoding("utf-8"))).gsub("\n", "")
  request = Typhoeus::Request.new(UnionpayApp.query_uri, method: :post, params: union_params.merge(signature: sign), ssl_verifypeer: false, headers: {'Content-Type' =>'application/x-www-form-urlencoded'} )
  request.run
  if request.response.success?
    code = Hash[*request.response.body.split("&").map{|a| a.gsub("==", "@@").split("=")}.flatten]['origRespCode']
  elsif request.response.timed_out?
    code = "got a time out"
  elsif request.response.code == 0
    code = request.response.return_message
  else
    code = request.response.code.to_s
  end
end

.sign(txtAmt, orderId) ⇒ Object

银联支付签名



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/unionpay_app/service.rb', line 10

def self.sign txtAmt, orderId
  union_params = {
    :version => "5.0.0",
    :encoding => "utf-8",
    :certId => UnionpayApp.cert_id,
    :txnType => '01',
    :txnSubType => "01",
    :bizType => "000201",
    :channelType => "08",
    :frontUrl   => UnionpayApp.front_url,
    :backUrl    => UnionpayApp.back_url,
    :accessType => "0",
    :merId      => UnionpayApp.mer_id,
    :orderId => orderId,  #商户订单号
    :txnTime => Time.now.strftime("%Y%m%d%H%M%S"),  #订单发送时间
    :txnAmt  => txtAmt, #以分为单位
    :currencyCode => '156',
    :signMethod => '01',
  }
  data = Digest::SHA1.hexdigest(union_params.sort.map{|key, value| "#{key}=#{value}" }.join('&'))
  sign = Base64.encode64(OpenSSL::PKey::RSA.new(UnionpayApp.private_key).sign('sha1', data.force_encoding("utf-8"))).gsub("\n", "")
  {time: union_params[:txnTime], sign: union_params.merge(signature: sign)}
end

.verify(params) ⇒ Object

银联支付验签



45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/unionpay_app/service.rb', line 45

def self.verify params
	if get_public_key_by_cert_id params['certId']
    public_key = get_public_key_by_cert_id params['certId']
    signature_str = params['signature']
    p = params.reject{|k, v| k == "signature"}.sort.map{|key, value| "#{key}=#{value}" }.join('&')
    signature = Base64.decode64(signature_str)
    data = Digest::SHA1.hexdigest(p)
    key = OpenSSL::PKey::RSA.new public_key
    digest = OpenSSL::Digest::SHA256.new
    key.verify digest, signature, data
	else
    false
	end
end