ecpay_payment 1.1.2
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 +7 -0
- data/Gemfile +4 -0
- data/Rakefile +6 -0
- data/conf/payment_conf.xml +29 -0
- data/ecpay.gemspec +25 -0
- data/lib/ecpay_payment/ECpayPayment.xml +623 -0
- data/lib/ecpay_payment/core_ext/hash.rb +13 -0
- data/lib/ecpay_payment/core_ext/string.rb +5 -0
- data/lib/ecpay_payment/error.rb +8 -0
- data/lib/ecpay_payment/exec_grant_refund.rb +82 -0
- data/lib/ecpay_payment/helper.rb +205 -0
- data/lib/ecpay_payment/payment_client.rb +217 -0
- data/lib/ecpay_payment/query_client.rb +142 -0
- data/lib/ecpay_payment/verification.rb +469 -0
- data/lib/ecpay_payment/version.rb +3 -0
- data/lib/ecpay_payment.rb +7 -0
- metadata +101 -0
| @@ -0,0 +1,82 @@ | |
| 1 | 
            +
            require "digest"
         | 
| 2 | 
            +
            require "uri"
         | 
| 3 | 
            +
            require "net/http"
         | 
| 4 | 
            +
            require "net/https"
         | 
| 5 | 
            +
            require "json"
         | 
| 6 | 
            +
            require "ecpay_payment/helper"
         | 
| 7 | 
            +
            require "ecpay_payment/verification"
         | 
| 8 | 
            +
            require "ecpay_payment/error"
         | 
| 9 | 
            +
            require "ecpay_payment/core_ext/hash"
         | 
| 10 | 
            +
            require "ecpay_payment/core_ext/string"
         | 
| 11 | 
            +
            #require "helper"
         | 
| 12 | 
            +
            #require "verification"
         | 
| 13 | 
            +
            #require "error"
         | 
| 14 | 
            +
            #require "core_ext/hash"
         | 
| 15 | 
            +
            #require "core_ext/string"
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            module ECpayPayment
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              class ECpayExecRefundAndGrant
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def initialize
         | 
| 22 | 
            +
                  @helper = APIHelper.new
         | 
| 23 | 
            +
                  #@verify_aiochkout = AioCheckOutParamVerify.new
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def credit_do_act(param)
         | 
| 28 | 
            +
                  act_base_proc!(params: param)
         | 
| 29 | 
            +
                  res = act_pos_proc!(params: param, apiname: 'DoAction')
         | 
| 30 | 
            +
                  return res
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def aio_capture(param)
         | 
| 34 | 
            +
                  act_base_proc!(params: param)
         | 
| 35 | 
            +
                  res = act_pos_proc!(params: param, apiname: 'Capture')
         | 
| 36 | 
            +
                  return res
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                ### Private method definition start ###
         | 
| 40 | 
            +
                private
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  def act_base_proc!(params:)
         | 
| 43 | 
            +
                    if params.is_a?(Hash)
         | 
| 44 | 
            +
                      # Transform param key to string
         | 
| 45 | 
            +
                      params.stringify_keys()
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                      # Process PlatformID & MerchantID by contractor setting
         | 
| 48 | 
            +
                      if @helper.is_contractor?
         | 
| 49 | 
            +
                        params['PlatformID'] = @helper.get_mercid
         | 
| 50 | 
            +
                        if params['MerchantID'].nil?
         | 
| 51 | 
            +
                          raise "[MerchantID] should be specified when you're contractor-Platform."
         | 
| 52 | 
            +
                        end
         | 
| 53 | 
            +
                      else
         | 
| 54 | 
            +
                        params['PlatformID'] = ''
         | 
| 55 | 
            +
                        params['MerchantID'] = @helper.get_mercid
         | 
| 56 | 
            +
                      end
         | 
| 57 | 
            +
                    else
         | 
| 58 | 
            +
                      raise ECpayInvalidParam, "Recieved parameter object must be a Hash"
         | 
| 59 | 
            +
                    end
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                  def act_pos_proc!(params:, apiname:)
         | 
| 63 | 
            +
                    verify_query_api = ECpayPayment::ActParamVerify.new(apiname)
         | 
| 64 | 
            +
                    verify_query_api.verify_act_param(params)
         | 
| 65 | 
            +
                    #encode special param
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                    # Insert chkmacval
         | 
| 68 | 
            +
                    chkmac = @helper.gen_chk_mac_value(params)
         | 
| 69 | 
            +
                    params['CheckMacValue'] = chkmac
         | 
| 70 | 
            +
                    # gen post html
         | 
| 71 | 
            +
                    api_url = verify_query_api.get_svc_url(apiname, @helper.get_op_mode)
         | 
| 72 | 
            +
                    #post from server
         | 
| 73 | 
            +
                    resp = @helper.http_request(method: 'POST', url: api_url, payload: params)
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                    # return  post response
         | 
| 76 | 
            +
                    return resp
         | 
| 77 | 
            +
                  end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                ### Private method definition end ###
         | 
| 80 | 
            +
             | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
            end
         | 
| @@ -0,0 +1,205 @@ | |
| 1 | 
            +
            require 'openssl'
         | 
| 2 | 
            +
            require 'base64'
         | 
| 3 | 
            +
            require 'digest'
         | 
| 4 | 
            +
            require 'uri'
         | 
| 5 | 
            +
            require 'cgi'
         | 
| 6 | 
            +
            require 'net/http'
         | 
| 7 | 
            +
            require 'nokogiri'
         | 
| 8 | 
            +
            require 'date'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            class APIHelper
         | 
| 11 | 
            +
                conf = File.join(File.dirname(__FILE__), '..', '..', 'conf', 'payment_conf.xml')
         | 
| 12 | 
            +
                @@conf_xml = Nokogiri::XML(File.open(conf))
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def initialize
         | 
| 15 | 
            +
                    active_merc_info = @@conf_xml.xpath('/Conf/MercProfile').text
         | 
| 16 | 
            +
                    @op_mode = @@conf_xml.xpath('/Conf/OperatingMode').text
         | 
| 17 | 
            +
                    @contractor_stat = @@conf_xml.xpath('/Conf/IsProjectContractor').text
         | 
| 18 | 
            +
                    merc_info = @@conf_xml.xpath("/Conf/MerchantInfo/MInfo[@name=\"#{active_merc_info}\"]")
         | 
| 19 | 
            +
                    @ignore_payment = []
         | 
| 20 | 
            +
                    @@conf_xml.xpath('/Conf/IgnorePayment//Method').each {|t| @ignore_payment.push(t.text)}
         | 
| 21 | 
            +
                    if merc_info != []
         | 
| 22 | 
            +
                        @merc_id = merc_info[0].xpath('./MerchantID').text.freeze
         | 
| 23 | 
            +
                        @hkey = merc_info[0].xpath('./HashKey').text.freeze
         | 
| 24 | 
            +
                        @hiv = merc_info[0].xpath('./HashIV').text.freeze
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    else
         | 
| 27 | 
            +
                        raise "Specified merchant setting name (#{active_merc_info}) not found."
         | 
| 28 | 
            +
                    end
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def get_mercid()
         | 
| 32 | 
            +
                    return @merc_id
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def get_op_mode()
         | 
| 36 | 
            +
                    return @op_mode
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                def get_ignore_pay()
         | 
| 40 | 
            +
                    return @ignore_payment
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def get_curr_unixtime()
         | 
| 44 | 
            +
                    return Time.now.to_i
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                def is_contractor?()
         | 
| 48 | 
            +
                    if @contractor_stat == 'N'
         | 
| 49 | 
            +
                        return false
         | 
| 50 | 
            +
                    elsif @contractor_stat == 'Y'
         | 
| 51 | 
            +
                        return true
         | 
| 52 | 
            +
                    else
         | 
| 53 | 
            +
                        raise "Unknown [IsProjectContractor] configuration."
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                def urlencode_dot_net(raw_data, case_tr:'DOWN')
         | 
| 58 | 
            +
                    if raw_data.is_a?(String)
         | 
| 59 | 
            +
                        encoded_data = CGI.escape(raw_data)
         | 
| 60 | 
            +
                        case case_tr
         | 
| 61 | 
            +
                        when 'KEEP'
         | 
| 62 | 
            +
                            # Do nothing
         | 
| 63 | 
            +
                        when 'UP'
         | 
| 64 | 
            +
                            encoded_data.upcase!
         | 
| 65 | 
            +
                        when 'DOWN'
         | 
| 66 | 
            +
                            encoded_data.downcase!
         | 
| 67 | 
            +
                        end
         | 
| 68 | 
            +
                        # Process encoding difference between .NET & CGI
         | 
| 69 | 
            +
                        encoded_data.gsub!('%21', '!')
         | 
| 70 | 
            +
                        encoded_data.gsub!('%2a', '*')
         | 
| 71 | 
            +
                        encoded_data.gsub!('%28', '(')
         | 
| 72 | 
            +
                        encoded_data.gsub!('%29', ')')
         | 
| 73 | 
            +
                        return encoded_data
         | 
| 74 | 
            +
                    else
         | 
| 75 | 
            +
                        raise "Data recieved is not a string."
         | 
| 76 | 
            +
                    end
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                def encode_special_param!(params, target_arr)
         | 
| 80 | 
            +
                    if params.is_a?(Hash)
         | 
| 81 | 
            +
                        target_arr.each do |n|
         | 
| 82 | 
            +
                            if params.keys.include?(n)
         | 
| 83 | 
            +
                                val = self.urlencode_dot_net(params[n])
         | 
| 84 | 
            +
                                params[n] = val
         | 
| 85 | 
            +
                            end
         | 
| 86 | 
            +
                        end
         | 
| 87 | 
            +
                    end
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                def gen_chk_mac_value(params, mode: 1)
         | 
| 91 | 
            +
                    if params.is_a?(Hash)
         | 
| 92 | 
            +
                        # raise exception if param contains CheckMacValue, HashKey, HashIV
         | 
| 93 | 
            +
                        sec = ['CheckMacValue', 'HashKey', 'HashIV']
         | 
| 94 | 
            +
                        sec.each do |pa|
         | 
| 95 | 
            +
                            if params.keys.include?(pa)
         | 
| 96 | 
            +
                                raise "Parameters shouldn't contain #{pa}"
         | 
| 97 | 
            +
                            end
         | 
| 98 | 
            +
                        end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                        raw = params.sort_by{|key,val|key.downcase}.map!{|key,val| "#{key}=#{val}"}.join('&')
         | 
| 101 | 
            +
                        raw = self.urlencode_dot_net(["HashKey=#{@hkey}", raw, "HashIV=#{@hiv}"].join("&"), case_tr: 'DOWN')
         | 
| 102 | 
            +
                        p raw
         | 
| 103 | 
            +
                        case mode
         | 
| 104 | 
            +
                        when 0
         | 
| 105 | 
            +
                        chksum = Digest::MD5.hexdigest(raw)
         | 
| 106 | 
            +
                        when 1
         | 
| 107 | 
            +
                        chksum = Digest::SHA256.hexdigest(raw)
         | 
| 108 | 
            +
                        else
         | 
| 109 | 
            +
                            raise "Unexpected hash mode."
         | 
| 110 | 
            +
                        end
         | 
| 111 | 
            +
                        return chksum.upcase!
         | 
| 112 | 
            +
                    else
         | 
| 113 | 
            +
                        raise "Data recieved is not a Hash."
         | 
| 114 | 
            +
                    end
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                def gen_aes_encrypt(params)
         | 
| 118 | 
            +
                    if params.is_a?(Hash)
         | 
| 119 | 
            +
                        # raise exception if param contains HashKey, HashIV
         | 
| 120 | 
            +
                        sec = ['HashKey', 'HashIV']
         | 
| 121 | 
            +
                        sec.each do |pa|
         | 
| 122 | 
            +
                            if params.keys.include?(pa)
         | 
| 123 | 
            +
                                raise "Parameters shouldn't contain #{pa}"
         | 
| 124 | 
            +
                            end
         | 
| 125 | 
            +
                        end
         | 
| 126 | 
            +
                        cipher = OpenSSL::Cipher.new('AES-128-CBC')
         | 
| 127 | 
            +
                        cipher.encrypt
         | 
| 128 | 
            +
                        cipher.padding = 16
         | 
| 129 | 
            +
                        cipher.key = @hkey
         | 
| 130 | 
            +
                        cipher.iv = @hiv
         | 
| 131 | 
            +
                        text = params['PaymentToken'].to_s
         | 
| 132 | 
            +
                        encrypted = cipher.update(text) + cipher.final
         | 
| 133 | 
            +
                        encrypted_base64 = Base64.encode64(encrypted)
         | 
| 134 | 
            +
                        return self.urlencode_dot_net(encrypted_base64)
         | 
| 135 | 
            +
                    else
         | 
| 136 | 
            +
                        raise "Data recieved is not a Hash."
         | 
| 137 | 
            +
                    end
         | 
| 138 | 
            +
                end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                def http_request(method:, url:, payload:)
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                    target_url = URI.parse(url)
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                    case method
         | 
| 145 | 
            +
                    when 'GET'
         | 
| 146 | 
            +
                      target_url.query = URI.encode_www_form(payload)
         | 
| 147 | 
            +
                      res = Net::HTTP.get_response(target_url)
         | 
| 148 | 
            +
                    when 'POST'
         | 
| 149 | 
            +
                      res = Net::HTTP.post_form(target_url, payload)
         | 
| 150 | 
            +
                    else
         | 
| 151 | 
            +
                      raise ArgumentError, "Only GET & POST method are avaliable."
         | 
| 152 | 
            +
                    end
         | 
| 153 | 
            +
                    return res.body
         | 
| 154 | 
            +
                    # if res == Net::HTTPOK
         | 
| 155 | 
            +
                    #     return res
         | 
| 156 | 
            +
                    # else
         | 
| 157 | 
            +
                    #     raise "#{res.message}, #{res}"
         | 
| 158 | 
            +
                    # end
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                    # when Net::HTTPClientError, Net::HTTPInternalServerError
         | 
| 161 | 
            +
                    #   raise Net::HTTPError.new(http_response.message, http_response)
         | 
| 162 | 
            +
                    # else
         | 
| 163 | 
            +
                    #   raise Net::HTTPError.new("Unexpected HTTP response.", http_response)
         | 
| 164 | 
            +
                    # end
         | 
| 165 | 
            +
                end
         | 
| 166 | 
            +
             | 
| 167 | 
            +
             | 
| 168 | 
            +
                def gen_html_post_form(act:, id:, parameters:, input_typ:'hidden', submit: true)
         | 
| 169 | 
            +
                    f = Nokogiri::HTML::Builder.new do |doc|
         | 
| 170 | 
            +
                        doc.form(method: 'post', action: act, id: id) {
         | 
| 171 | 
            +
                            parameters.map{|key,val|
         | 
| 172 | 
            +
                            doc.input(type: input_typ, name: key, id: key, value: val)
         | 
| 173 | 
            +
                            }
         | 
| 174 | 
            +
                            if submit == true
         | 
| 175 | 
            +
                                doc.script(type: 'text/javascript').text("document.getElementById(\"#{id}\").submit();")
         | 
| 176 | 
            +
                            end
         | 
| 177 | 
            +
                        }
         | 
| 178 | 
            +
                    end
         | 
| 179 | 
            +
                    return f.to_html
         | 
| 180 | 
            +
                end
         | 
| 181 | 
            +
             | 
| 182 | 
            +
             | 
| 183 | 
            +
                def valid_chkmac_string?(str)
         | 
| 184 | 
            +
                    rtn_hash = {}
         | 
| 185 | 
            +
                    rtn_list = str.split('&')
         | 
| 186 | 
            +
                    rtn_list.each do |e|
         | 
| 187 | 
            +
                        param = e.split('=')
         | 
| 188 | 
            +
                        rtn_hash[param[0]] = param[1]
         | 
| 189 | 
            +
                    end
         | 
| 190 | 
            +
                    chkmac = rtn_hash['CheckMacValue']
         | 
| 191 | 
            +
                    rtn_hash.delete('CheckMacValue')
         | 
| 192 | 
            +
                    if chkmac.length == 64
         | 
| 193 | 
            +
                        val = gen_chk_mac_value(rtn_hash)
         | 
| 194 | 
            +
                    elsif chkmac.length == 32
         | 
| 195 | 
            +
                        val = gen_chk_mac_value(rtn_hash, mode: 0)
         | 
| 196 | 
            +
                    end
         | 
| 197 | 
            +
                    if chkmac == val
         | 
| 198 | 
            +
                        return true
         | 
| 199 | 
            +
                    else
         | 
| 200 | 
            +
                        return false
         | 
| 201 | 
            +
                    end
         | 
| 202 | 
            +
             | 
| 203 | 
            +
                end
         | 
| 204 | 
            +
             | 
| 205 | 
            +
            end
         | 
| @@ -0,0 +1,217 @@ | |
| 1 | 
            +
            require "digest"
         | 
| 2 | 
            +
            require "uri"
         | 
| 3 | 
            +
            require "net/http"
         | 
| 4 | 
            +
            require "net/https"
         | 
| 5 | 
            +
            require "json"
         | 
| 6 | 
            +
            require "ecpay_payment/helper"
         | 
| 7 | 
            +
            require "ecpay_payment/verification"
         | 
| 8 | 
            +
            require "ecpay_payment/error"
         | 
| 9 | 
            +
            require "ecpay_payment/core_ext/hash"
         | 
| 10 | 
            +
            require "ecpay_payment/core_ext/string"
         | 
| 11 | 
            +
            # require "../../../gem/lib/ecpay_payment/helper"
         | 
| 12 | 
            +
            # require "../../../gem/lib/ecpay_payment/verification"
         | 
| 13 | 
            +
            # require "../../../gem/lib/ecpay_payment/error"
         | 
| 14 | 
            +
            # require "../../../gem/lib/ecpay_payment/core_ext/hash"
         | 
| 15 | 
            +
            # require "../../../gem/lib/ecpay_payment/core_ext/string"
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            module ECpayPayment
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            	class ECpayPaymentClient
         | 
| 20 | 
            +
                include ECpayErrorDefinition
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            		def initialize
         | 
| 23 | 
            +
                  @helper = APIHelper.new
         | 
| 24 | 
            +
                  @verify_aiochkout = ECpayPayment::AioCheckOutParamVerify.new
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def aio_check_out_all(params:, invoice:{})
         | 
| 29 | 
            +
                  unsupport = []
         | 
| 30 | 
            +
                  aiochkout_base_proc!(params: params, invoice: invoice, unsupport_param: unsupport, pay_method: 'ALL')
         | 
| 31 | 
            +
                  # handle Ignore Payment
         | 
| 32 | 
            +
                  params['IgnorePayment'] = @helper.get_ignore_pay.join('#')
         | 
| 33 | 
            +
                  html = aiochkout_pos_proc!(params: params)
         | 
| 34 | 
            +
                  return html
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                def aio_check_out_credit_onetime(params:, invoice:{})
         | 
| 39 | 
            +
                  unsupport = ['HoldTradeAMT', 'IgnorePayment']
         | 
| 40 | 
            +
                  aiochkout_base_proc!(params: params, invoice: invoice, unsupport_param: unsupport, pay_method: 'Credit')
         | 
| 41 | 
            +
                  html = aiochkout_pos_proc!(params: params)
         | 
| 42 | 
            +
                  return html
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                def aio_check_out_applepay(params:, invoice:{})
         | 
| 46 | 
            +
                  unsupport = ['HoldTradeAMT', 'IgnorePayment']
         | 
| 47 | 
            +
                  aiochkout_base_proc!(params: params, invoice: invoice, unsupport_param: unsupport, pay_method: 'ApplePay')
         | 
| 48 | 
            +
                  html = aiochkout_pos_proc!(params: params)
         | 
| 49 | 
            +
                  return html
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
                #2019/09/30暫時關閉GooglePay付款方式
         | 
| 52 | 
            +
                # def aio_check_out_googlepay(params:, invoice:{})
         | 
| 53 | 
            +
                #   unsupport = ['HoldTradeAMT', 'IgnorePayment']
         | 
| 54 | 
            +
                #   aiochkout_base_proc!(params: params, invoice: invoice, unsupport_param: unsupport, pay_method: 'GooglePay')
         | 
| 55 | 
            +
                #   html = aiochkout_pos_proc!(params: params)
         | 
| 56 | 
            +
                #   return html
         | 
| 57 | 
            +
                # end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                def aio_check_out_credit_divide(params:, invoice:{}, installment: )
         | 
| 60 | 
            +
                  unsupport = ['HoldTradeAMT', 'IgnorePayment', 'Redeem', 'PeriodAmount', 'PeriodType', 'Frequency', 'ExecTimes', 'PeriodReturnURL']
         | 
| 61 | 
            +
                  aiochkout_base_proc!(params: params, invoice: invoice, unsupport_param: unsupport, pay_method: 'Credit')
         | 
| 62 | 
            +
                  params['CreditInstallment'] = installment
         | 
| 63 | 
            +
                  html = aiochkout_pos_proc!(params: params)
         | 
| 64 | 
            +
                  return html
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                def aio_check_out_credit_period(period_info:, params:, invoice:{})
         | 
| 68 | 
            +
                  # 'PeriodAmount', 'PeriodType', 'Frequency', 'ExecTimes', 'PeriodReturnURL'
         | 
| 69 | 
            +
                  unsupport = ['HoldTradeAMT', 'IgnorePayment', 'Redeem', 'CreditInstallment', 'InstallmentAmount']
         | 
| 70 | 
            +
                  aiochkout_base_proc!(params: params, invoice: invoice, unsupport_param: unsupport, pay_method: 'Credit')
         | 
| 71 | 
            +
                  if period_info.is_a?(Hash)
         | 
| 72 | 
            +
                    period_args = ['PeriodAmount', 'PeriodType', 'Frequency', 'ExecTimes', 'PeriodReturnURL']
         | 
| 73 | 
            +
                    if period_info.keys.sort() == period_args.sort()
         | 
| 74 | 
            +
                      params.merge!(period_info)
         | 
| 75 | 
            +
                      # Add total amount protection!!!
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                      html = aiochkout_pos_proc!(params: params)
         | 
| 78 | 
            +
                      return html
         | 
| 79 | 
            +
                    else
         | 
| 80 | 
            +
                      raise "Credit card period parameters must be #{period_args}."
         | 
| 81 | 
            +
                    end
         | 
| 82 | 
            +
                  else
         | 
| 83 | 
            +
                    raise "Recieved period_info argument must be a Hash."
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                def aio_check_out_atm(params:, url_return_payinfo:'', exp_period:'', client_redirect:'', invoice:{})
         | 
| 89 | 
            +
                  unsupport = ['IgnorePayment']
         | 
| 90 | 
            +
                  aiochkout_base_proc!(params: params, invoice: invoice, unsupport_param: unsupport, pay_method: 'ATM')
         | 
| 91 | 
            +
                  if exp_period == ''
         | 
| 92 | 
            +
                    params.delete('ExpireDate')
         | 
| 93 | 
            +
                  else
         | 
| 94 | 
            +
                    params['ExpireDate'] = exp_period
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
            			if client_redirect == ''
         | 
| 97 | 
            +
                    params.delete('ClientRedirectURL')
         | 
| 98 | 
            +
            			else
         | 
| 99 | 
            +
            				params['ClientRedirectURL'] = client_redirect
         | 
| 100 | 
            +
                  end
         | 
| 101 | 
            +
            			if url_return_payinfo == ''
         | 
| 102 | 
            +
                    params.delete('PaymentInfoURL')
         | 
| 103 | 
            +
            			else
         | 
| 104 | 
            +
            				params['PaymentInfoURL'] = url_return_payinfo
         | 
| 105 | 
            +
                  end
         | 
| 106 | 
            +
                  html = aiochkout_pos_proc!(params: params)
         | 
| 107 | 
            +
                  return html
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                def aio_check_out_webatm(params:, invoice:{})
         | 
| 111 | 
            +
                  unsupport = ['IgnorePayment']
         | 
| 112 | 
            +
                  aiochkout_base_proc!(params: params, invoice: invoice, unsupport_param: unsupport, pay_method: 'WebATM')
         | 
| 113 | 
            +
                  html = aiochkout_pos_proc!(params: params)
         | 
| 114 | 
            +
                  return html
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                def aio_check_out_cvs(cvs_info:, params:, invoice:{}, client_redirect_url:'')
         | 
| 118 | 
            +
                  unsupport = ['IgnorePayment']
         | 
| 119 | 
            +
                  aiochkout_base_proc!(params: params, invoice: invoice, unsupport_param: unsupport, pay_method: 'CVS')
         | 
| 120 | 
            +
                  if cvs_info.is_a?(Hash)
         | 
| 121 | 
            +
                    cvs_args = ['StoreExpireDate', 'Desc_1', 'Desc_2', 'Desc_3', 'Desc_4', 'PaymentInfoURL']
         | 
| 122 | 
            +
                    if cvs_info.keys.sort() == cvs_args.sort()
         | 
| 123 | 
            +
                      params.merge!(cvs_info)
         | 
| 124 | 
            +
                      if client_redirect_url == '' or client_redirect_url.nil?
         | 
| 125 | 
            +
                        params.delete('ClientRedirectURL')
         | 
| 126 | 
            +
                      else
         | 
| 127 | 
            +
                        params['ClientRedirectURL'] = client_redirect_url
         | 
| 128 | 
            +
                      end
         | 
| 129 | 
            +
                      html = aiochkout_pos_proc!(params: params)
         | 
| 130 | 
            +
                      return html
         | 
| 131 | 
            +
                    else
         | 
| 132 | 
            +
                      raise "CVS info keys must match #{cvs_args}."
         | 
| 133 | 
            +
                    end
         | 
| 134 | 
            +
                  else
         | 
| 135 | 
            +
                    raise "Recieved cvs_info argument must be a Hash."
         | 
| 136 | 
            +
                  end
         | 
| 137 | 
            +
                end
         | 
| 138 | 
            +
             | 
| 139 | 
            +
            		def aio_check_out_barcode(barcode_info:, params:, invoice:{}, client_redirect_url:'')
         | 
| 140 | 
            +
                  unsupport = ['IgnorePayment']
         | 
| 141 | 
            +
                  aiochkout_base_proc!(params: params, invoice: invoice, unsupport_param: unsupport, pay_method: 'BARCODE')
         | 
| 142 | 
            +
                  if barcode_info.is_a?(Hash)
         | 
| 143 | 
            +
                    barcode_args = ['StoreExpireDate', 'Desc_1', 'Desc_2', 'Desc_3', 'Desc_4', 'PaymentInfoURL']
         | 
| 144 | 
            +
                    if barcode_info.keys.sort() == barcode_args.sort()
         | 
| 145 | 
            +
                      params.merge!(barcode_info)
         | 
| 146 | 
            +
                      if client_redirect_url == '' or client_redirect_url.nil?
         | 
| 147 | 
            +
                        params.delete('ClientRedirectURL')
         | 
| 148 | 
            +
                      else
         | 
| 149 | 
            +
                        params['ClientRedirectURL'] = client_redirect_url
         | 
| 150 | 
            +
                      end
         | 
| 151 | 
            +
                      html = aiochkout_pos_proc!(params: params)
         | 
| 152 | 
            +
                      return html
         | 
| 153 | 
            +
                    else
         | 
| 154 | 
            +
                      raise "BARCODE info keys must match #{barcode_args}."
         | 
| 155 | 
            +
                    end
         | 
| 156 | 
            +
                  else
         | 
| 157 | 
            +
                    raise "Recieved barcode_info argument must be a Hash."
         | 
| 158 | 
            +
                  end
         | 
| 159 | 
            +
                end
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                ### Private method definition start ###
         | 
| 162 | 
            +
                private
         | 
| 163 | 
            +
                  def aiochkout_base_proc!(params:, invoice:{}, unsupport_param:, pay_method:)
         | 
| 164 | 
            +
                    if params.is_a?(Hash)
         | 
| 165 | 
            +
                      # Transform param key to string
         | 
| 166 | 
            +
                      params.stringify_keys()
         | 
| 167 | 
            +
                      # Remove HoldTradeAMT, IgnorePayment
         | 
| 168 | 
            +
                      if unsupport_param.is_a?(Array)
         | 
| 169 | 
            +
                        unsupport_param.each{|pa|params.delete(pa)}
         | 
| 170 | 
            +
                      else
         | 
| 171 | 
            +
                        raise "argument unsupport_param must be an Array."
         | 
| 172 | 
            +
                      end
         | 
| 173 | 
            +
                      # User doesn't have to specify ChoosePayment
         | 
| 174 | 
            +
                      params['ChoosePayment'] = pay_method
         | 
| 175 | 
            +
                      # Process PlatformID & MerchantID by contractor setting
         | 
| 176 | 
            +
                      if @helper.is_contractor?
         | 
| 177 | 
            +
                        params['PlatformID'] = @helper.get_mercid
         | 
| 178 | 
            +
                        if params['MerchantID'].nil?
         | 
| 179 | 
            +
                          raise "[MerchantID] should be specified when you're contractor-Platform."
         | 
| 180 | 
            +
                        end
         | 
| 181 | 
            +
                      else
         | 
| 182 | 
            +
                        params['PlatformID'] = ''
         | 
| 183 | 
            +
                        params['MerchantID'] = @helper.get_mercid
         | 
| 184 | 
            +
                      end
         | 
| 185 | 
            +
                      # InvoiceMark based on keyword argument: invoice
         | 
| 186 | 
            +
                      if invoice == {}
         | 
| 187 | 
            +
                        params['InvoiceMark'] = 'N'
         | 
| 188 | 
            +
                      else
         | 
| 189 | 
            +
                        params['InvoiceMark'] = 'Y'
         | 
| 190 | 
            +
                        @verify_aiochkout.verify_aio_inv_param(invoice)
         | 
| 191 | 
            +
                        #merge param & inv param
         | 
| 192 | 
            +
                        params.merge!(invoice)
         | 
| 193 | 
            +
                      end
         | 
| 194 | 
            +
                    else
         | 
| 195 | 
            +
                      raise ECpayInvalidParam, "Recieved parameter object must be a Hash"
         | 
| 196 | 
            +
                    end
         | 
| 197 | 
            +
                  end
         | 
| 198 | 
            +
             | 
| 199 | 
            +
                  def aiochkout_pos_proc!(params:)
         | 
| 200 | 
            +
                    @verify_aiochkout.verify_aio_payment_param(params)
         | 
| 201 | 
            +
                    #encode special param
         | 
| 202 | 
            +
                    sp_param = @verify_aiochkout.get_special_encode_param('AioCheckOut')
         | 
| 203 | 
            +
                    @helper.encode_special_param!(params, sp_param)
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                    # Insert chkmacval
         | 
| 206 | 
            +
                    chkmac = @helper.gen_chk_mac_value(params)
         | 
| 207 | 
            +
                    params['CheckMacValue'] = chkmac
         | 
| 208 | 
            +
                    # gen post html
         | 
| 209 | 
            +
                    api_url = @verify_aiochkout.get_svc_url('AioCheckOut', @helper.get_op_mode)
         | 
| 210 | 
            +
                    htm = @helper.gen_html_post_form(act: api_url, id: '_form_aiochk', parameters: params)
         | 
| 211 | 
            +
                    # return  post htm
         | 
| 212 | 
            +
                    return htm
         | 
| 213 | 
            +
                  end
         | 
| 214 | 
            +
                ### Private method definition end ###
         | 
| 215 | 
            +
             | 
| 216 | 
            +
              end
         | 
| 217 | 
            +
            end
         | 
| @@ -0,0 +1,142 @@ | |
| 1 | 
            +
            require "digest"
         | 
| 2 | 
            +
            require "uri"
         | 
| 3 | 
            +
            require "net/http"
         | 
| 4 | 
            +
            require "net/https"
         | 
| 5 | 
            +
            require "json"
         | 
| 6 | 
            +
            require "date"
         | 
| 7 | 
            +
            require "ecpay_payment/helper"
         | 
| 8 | 
            +
            require "ecpay_payment/verification"
         | 
| 9 | 
            +
            require "ecpay_payment/error"
         | 
| 10 | 
            +
            require "ecpay_payment/core_ext/hash"
         | 
| 11 | 
            +
            require "ecpay_payment/core_ext/string"
         | 
| 12 | 
            +
            # require "../../../gem/lib/ecpay_payment/helper"
         | 
| 13 | 
            +
            # require "../../../gem/lib/ecpay_payment/verification"
         | 
| 14 | 
            +
            # require "../../../gem/lib/ecpay_payment/error"
         | 
| 15 | 
            +
            # require "../../../gem/lib/ecpay_payment/core_ext/hash"
         | 
| 16 | 
            +
            # require "../../../gem/lib/ecpay_payment/core_ext/string"
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            module ECpayPayment
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              class ECpayQueryClient
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                def initialize
         | 
| 23 | 
            +
                  @helper = APIHelper.new
         | 
| 24 | 
            +
                  #@verify_query_api = QueryTradeInfoParamVerify.new
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def create_server_order(param)
         | 
| 29 | 
            +
                  query_base_proc!(params: param)
         | 
| 30 | 
            +
                  res = query_pos_proc!(params: param, apiname: 'CreateServerOrder')
         | 
| 31 | 
            +
                  return res
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def query_trade_info(param)
         | 
| 35 | 
            +
                  query_base_proc!(params: param)
         | 
| 36 | 
            +
                  unix_time = get_curr_unix_time() + 120
         | 
| 37 | 
            +
                  param['TimeStamp'] = unix_time.to_s
         | 
| 38 | 
            +
                  p param['TimeStamp']
         | 
| 39 | 
            +
                  res = query_pos_proc!(params: param, apiname: 'QueryTradeInfo')
         | 
| 40 | 
            +
                  return res
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def query_credit_period(param)
         | 
| 44 | 
            +
                  query_base_proc!(params: param)
         | 
| 45 | 
            +
                  unix_time = get_curr_unix_time() + 120
         | 
| 46 | 
            +
                  param['TimeStamp'] = unix_time.to_s
         | 
| 47 | 
            +
                  p param['TimeStamp']
         | 
| 48 | 
            +
                  param.delete('PlatformID')
         | 
| 49 | 
            +
                  res = query_pos_proc!(params: param, apiname: 'QueryCreditCardPeriodInfo')
         | 
| 50 | 
            +
                  return res
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                def query_transac_csv(param)
         | 
| 54 | 
            +
                  query_base_proc!(params: param)
         | 
| 55 | 
            +
                  param.delete('PlatformID')
         | 
| 56 | 
            +
                  res = query_pos_proc!(params: param, apiname: 'TradeNoAio', big5_trans: true)
         | 
| 57 | 
            +
                  return res
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                def query_credit_single(param)
         | 
| 61 | 
            +
                  query_base_proc!(params: param)
         | 
| 62 | 
            +
                  param.delete('PlatformID')
         | 
| 63 | 
            +
                  res = query_pos_proc!(params: param, apiname: 'QueryTradeV2')
         | 
| 64 | 
            +
                  return res
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                def query_credit_csv(param)
         | 
| 68 | 
            +
                  query_base_proc!(params: param)
         | 
| 69 | 
            +
                  param.delete('PlatformID')
         | 
| 70 | 
            +
                  res = query_pos_proc!(params: param, apiname: 'FundingReconDetail')
         | 
| 71 | 
            +
                  return res
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
             | 
| 75 | 
            +
             | 
| 76 | 
            +
                ### Private method definition start ###
         | 
| 77 | 
            +
                private
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                  def get_curr_unix_time()
         | 
| 80 | 
            +
                    return Time.now.to_i
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  def query_base_proc!(params:)
         | 
| 84 | 
            +
                    if params.is_a?(Hash)
         | 
| 85 | 
            +
                      # Transform param key to string
         | 
| 86 | 
            +
                      params.stringify_keys()
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                      if @helper.is_contractor?
         | 
| 89 | 
            +
                        params['PlatformID'] = @helper.get_mercid
         | 
| 90 | 
            +
                        if params['MerchantID'].nil?
         | 
| 91 | 
            +
                          raise "[MerchantID] should be specified when you're contractor-Platform."
         | 
| 92 | 
            +
                        end
         | 
| 93 | 
            +
                      else
         | 
| 94 | 
            +
                        params['PlatformID'] = ''
         | 
| 95 | 
            +
                        params['MerchantID'] = @helper.get_mercid
         | 
| 96 | 
            +
                      end
         | 
| 97 | 
            +
                    else
         | 
| 98 | 
            +
                      raise ECpayInvalidParam, "Recieved parameter object must be a Hash"
         | 
| 99 | 
            +
                    end
         | 
| 100 | 
            +
                  end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  def query_pos_proc!(params:, apiname:, big5_trans:false)
         | 
| 103 | 
            +
                    verify_query_api = ECpayPayment::QueryParamVerify.new(apiname)
         | 
| 104 | 
            +
                    verify_query_api.verify_query_param(params)
         | 
| 105 | 
            +
                    if apiname == 'CreateServerOrder'
         | 
| 106 | 
            +
                      exclusive_list = ['PaymentToken']
         | 
| 107 | 
            +
                    else
         | 
| 108 | 
            +
                      exclusive_list = []
         | 
| 109 | 
            +
                    end
         | 
| 110 | 
            +
                    #encode special param
         | 
| 111 | 
            +
                    # for PaymentToken
         | 
| 112 | 
            +
                    exclusive_ele = {}
         | 
| 113 | 
            +
                    for param in exclusive_list
         | 
| 114 | 
            +
                      exclusive_ele[param] = params[param]
         | 
| 115 | 
            +
                      params.delete(param)
         | 
| 116 | 
            +
                    end
         | 
| 117 | 
            +
                    # Insert chkmacval
         | 
| 118 | 
            +
                    chkmac = @helper.gen_chk_mac_value(params)
         | 
| 119 | 
            +
                    params['CheckMacValue'] = chkmac
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                    for param in exclusive_list
         | 
| 122 | 
            +
                      paymenttoken = @helper.gen_aes_encrypt(exclusive_ele)
         | 
| 123 | 
            +
                      params[param] = paymenttoken
         | 
| 124 | 
            +
                    end
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                    # gen post html
         | 
| 127 | 
            +
                    api_url = verify_query_api.get_svc_url(apiname, @helper.get_op_mode)
         | 
| 128 | 
            +
                    p params
         | 
| 129 | 
            +
                    #post from server
         | 
| 130 | 
            +
                    resp = @helper.http_request(method: 'POST', url: api_url, payload: params)
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                    # return  post response
         | 
| 133 | 
            +
                    if big5_trans
         | 
| 134 | 
            +
                      return resp.encode('utf-8', 'big5')
         | 
| 135 | 
            +
                    else
         | 
| 136 | 
            +
                      return resp
         | 
| 137 | 
            +
                    end
         | 
| 138 | 
            +
                  end
         | 
| 139 | 
            +
                ### Private method definition end ###
         | 
| 140 | 
            +
             | 
| 141 | 
            +
              end
         | 
| 142 | 
            +
            end
         |