From 1fa6ade437289662de34647f24a1910df7dcff3b Mon Sep 17 00:00:00 2001 From: jasl Date: Tue, 11 Nov 2014 05:29:56 +0800 Subject: [PATCH] first functional version --- README.md | 35 ++++++++++++++++++++++++++++++++++- lib/wx_pay.rb | 3 +-- lib/wx_pay/notify.rb | 18 ------------------ lib/wx_pay/result.rb | 19 +++++++++++++++++++ lib/wx_pay/service.rb | 29 +++++++++++++++++++++++++++-- lib/wx_pay/sign.rb | 4 ++-- lib/wx_pay/utils.rb | 27 --------------------------- lib/wx_pay/version.rb | 2 +- test/test_helper.rb | 1 + test/wx_pay/result_test.rb | 29 +++++++++++++++++++++++++++++ test/wx_pay/sign_test.rb | 2 +- test/wx_pay/utils_test.rb | 8 -------- 12 files changed, 115 insertions(+), 62 deletions(-) delete mode 100644 lib/wx_pay/notify.rb create mode 100644 lib/wx_pay/result.rb delete mode 100644 lib/wx_pay/utils.rb create mode 100644 test/wx_pay/result_test.rb delete mode 100644 test/wx_pay/utils_test.rb diff --git a/README.md b/README.md index e52ef13..7e11551 100644 --- a/README.md +++ b/README.md @@ -30,14 +30,47 @@ $ bundle ### Config ```ruby +# required WxPay.appid = 'YOUR_APPID' WxPay.key = 'YOUR_KEY' WxPay.mch_id = 'YOUR_MCH_ID' + +# optional +WxPay.extra_rest_client_options = {timeout: 2, open_timeout: 3} ``` ### APIs -**PLACEHOLDER** +**Check official document for detailed request params and return fields** + +#### unifiedorder + +```ruby +# required fields +params = { +body: '测试商品', +out_trade_no: 'test003', +total_fee: 1, +spbill_create_ip: '127.0.0.1', +notify_url: 'http://making.dev', +trade_type: 'JSAPI' +} + +# Return a WxPay::Result instance(subclass of Hash) contains parsed result +r = WxPay::Service.invoke_unifiedorder params +# => {"return_code"=>"SUCCESS", +# "return_msg"=>"OK", +# "appid"=>"YOUR APPID", +# "mch_id"=>"YOUR MCH_ID", +# "nonce_str"=>"8RN7YfTZ3OUgWX5e", +# "sign"=>"623AE90C9679729DDD7407DC7A1151B2", +# "result_code"=>"SUCCESS", +# "prepay_id"=>"wx2014111104255143b7605afb0314593866", +# "trade_type"=>"JSAPI"} + +# Return true if both return_code and result_code equal SUCCESS +r.success? # => true +``` ## Contributing diff --git a/lib/wx_pay.rb b/lib/wx_pay.rb index 9cdb48d..72ef3a9 100644 --- a/lib/wx_pay.rb +++ b/lib/wx_pay.rb @@ -1,7 +1,6 @@ -require 'wx_pay/utils' +require 'wx_pay/result' require 'wx_pay/sign' require 'wx_pay/service' -require 'wx_pay/notify' module WxPay class<< self diff --git a/lib/wx_pay/notify.rb b/lib/wx_pay/notify.rb deleted file mode 100644 index 01c3b59..0000000 --- a/lib/wx_pay/notify.rb +++ /dev/null @@ -1,18 +0,0 @@ -module WxPay - module Notify - GATEWAY = 'https://gw.tenpay.com/gateway/simpleverifynotifyid.xml' - SUCCESS_STR = '0' - - def self.verify?(params) - return false unless Sign.verify?(params) - - params = { - 'input_charset' => 'UTF-8', - 'partner' => WxPay.appid, - 'notify_id' => CGI.escape(params[:notify_id].to_s) - } - - open("#{GATEWAY}?#{Utils.make_query_string(params)}").read.include?(SUCCESS_STR) - end - end -end diff --git a/lib/wx_pay/result.rb b/lib/wx_pay/result.rb new file mode 100644 index 0000000..92622fe --- /dev/null +++ b/lib/wx_pay/result.rb @@ -0,0 +1,19 @@ +module WxPay + class Result < ::Hash + SUCCESS_FLAG = 'SUCCESS'.freeze + + def initialize(result) + super + + if result['xml'].class == Hash + result['xml'].each_pair do |k, v| + self[k] = v + end + end + end + + def success? + self['return_code'] == SUCCESS_FLAG && self['result_code'] == SUCCESS_FLAG + end + end +end diff --git a/lib/wx_pay/service.rb b/lib/wx_pay/service.rb index 6808805..f47eb94 100644 --- a/lib/wx_pay/service.rb +++ b/lib/wx_pay/service.rb @@ -8,14 +8,18 @@ module WxPay INVOKE_UNIFIEDORDER_REQUIRED_FIELDS = %i(body out_trade_no total_fee spbill_create_ip notify_url trade_type) def self.invoke_unifiedorder(params) params = { - app_id: WxPay.appid, + appid: WxPay.appid, mch_id: WxPay.mch_id, nonce_str: SecureRandom.uuid.tr('-', ''), }.merge(params) check_required_options(params, INVOKE_UNIFIEDORDER_REQUIRED_FIELDS) - WxPay::Utils.invoke_remote("#{GATEWAY_URL}/unifiedorder", WxPay::Utils.make_payload(params)) + r = invoke_remote("#{GATEWAY_URL}/unifiedorder", make_payload(params)) + + yield r if block_given? + + r end private @@ -25,5 +29,26 @@ module WxPay warn("WxPay Warn: missing required option: #{name}") unless options.has_key?(name) end end + + def self.make_payload(params) + "#{params.map { |k, v| "<#{k}>#{v}" }.join}#{WxPay::Sign.generate(params)}" + end + + def self.invoke_remote(url, payload) + r = RestClient::Request.execute( + { + method: :post, + url: url, + payload: payload, + headers: { content_type: 'application/xml' } + }.merge(WxPay.extra_rest_client_options) + ) + + if r + WxPay::Result.new Hash.from_xml(r) + else + nil + end + end end end diff --git a/lib/wx_pay/sign.rb b/lib/wx_pay/sign.rb index be44a53..9b54061 100644 --- a/lib/wx_pay/sign.rb +++ b/lib/wx_pay/sign.rb @@ -11,8 +11,8 @@ module WxPay end def self.verify?(params) - params = Utils.stringify_keys(params) - sign = params.delete('sign') + params = params.dup + sign = params.delete('sign') || params.delete(:sign) generate(params) == sign end diff --git a/lib/wx_pay/utils.rb b/lib/wx_pay/utils.rb deleted file mode 100644 index 5585866..0000000 --- a/lib/wx_pay/utils.rb +++ /dev/null @@ -1,27 +0,0 @@ -module WxPay - module Utils - def self.stringify_keys(hash) - new_hash = {} - hash.each do |key, value| - new_hash[(key.to_s rescue key) || key] = value - end - new_hash - end - - def self.make_payload(params) - "#{params.map {|k, v| "<#{k}>#{v}"}.join}#{WxPay::Sign.generate(params)}" - end - - def self.invoke_remote(url, payload) - Hash.from_xml( - RestClient::Request.execute( - { - method: :post, - url: url, - payload: payload, - headers: {content_type: 'application/xml'} - }.merge(WxPay.extra_rest_client_options)) - ) - end - end -end diff --git a/lib/wx_pay/version.rb b/lib/wx_pay/version.rb index b867320..b74bf19 100644 --- a/lib/wx_pay/version.rb +++ b/lib/wx_pay/version.rb @@ -1,3 +1,3 @@ module WxPay - VERSION = "0.0.1" + VERSION = "0.0.2" end diff --git a/test/test_helper.rb b/test/test_helper.rb index 6420426..5f9e6f8 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,3 +1,4 @@ +require 'active_support/core_ext/hash/conversions' require 'minitest/autorun' require 'wx_pay' require 'fakeweb' diff --git a/test/wx_pay/result_test.rb b/test/wx_pay/result_test.rb new file mode 100644 index 0000000..47e2b2c --- /dev/null +++ b/test/wx_pay/result_test.rb @@ -0,0 +1,29 @@ +require 'test_helper' + +class WxPay::ResultTest < MiniTest::Test + def test_success_method_with_true + r = WxPay::Result.new( + Hash.from_xml( + <<-XML + + SUCCESS + SUCCESS + + XML + )) + + assert_equal r.success?, true + end + + def test_success_method_with_false + r = WxPay::Result.new( + Hash.from_xml( + <<-XML + + + XML + )) + + assert_equal r.success?, false + end +end diff --git a/test/wx_pay/sign_test.rb b/test/wx_pay/sign_test.rb index 7a8cd4e..7b4a5e6 100644 --- a/test/wx_pay/sign_test.rb +++ b/test/wx_pay/sign_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class WxPay::SignTest < MiniTest::Unit::TestCase +class WxPay::SignTest < MiniTest::Test def setup @params = { appid: 'wxd930ea5d5a258f4f', diff --git a/test/wx_pay/utils_test.rb b/test/wx_pay/utils_test.rb deleted file mode 100644 index 520e1a7..0000000 --- a/test/wx_pay/utils_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -require 'test_helper' - -class WxPay::UtilsTest < MiniTest::Unit::TestCase - def test_stringify_keys - hash = { 'a' => 1, :b => 2 } - assert_equal({ 'a' => 1, 'b' => 2 }.sort, WxPay::Utils.stringify_keys(hash).sort) - end -end -- libgit2 0.21.0