khipu 1.3.0
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/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +29 -0
- data/README.md +229 -0
- data/Rakefile +7 -0
- data/khipu.gemspec +26 -0
- data/lib/khipu/api_error.rb +10 -0
- data/lib/khipu/const.rb +59 -0
- data/lib/khipu/html_helper.rb +53 -0
- data/lib/khipu/khipu_api_endpoint.rb +184 -0
- data/lib/khipu/khipu_service.rb +76 -0
- data/lib/khipu/version.rb +3 -0
- data/lib/khipu.rb +45 -0
- data/spec/khipu_service_spec.rb +17 -0
- data/spec/spec_helper.rb +1 -0
- metadata +103 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: bbdd3f10aea423ebab6c1e4801ae8cd3dd0da2f1
         | 
| 4 | 
            +
              data.tar.gz: ee8f254750eef7c4e1beb041adc251a872bbd0c2
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: d4da9dff3275f4eca53ff9d835d166b26672a0dc65b5f7f71b1b35c2cf50e0774b1ea905d3c494e57dd7d2733d40a3eb71207f16f71438f060f1c801ca8a3f21
         | 
| 7 | 
            +
              data.tar.gz: e8aeca81768df4f5519c30f466349ba3cd25d4d97dd0b084754ab6bf372712eb4b58ebe08c55f2b1ff050f55db033a0a23e77f1143fbfdf50ae11a53d567c6da
         | 
    
        data/.gitignore
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE.txt
    ADDED
    
    | @@ -0,0 +1,29 @@ | |
| 1 | 
            +
            Copyright (c) 2014, khipu SpA
         | 
| 2 | 
            +
            All rights reserved.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            Redistribution and use in source and binary forms, with or without
         | 
| 5 | 
            +
            modification, are permitted provided that the following conditions are
         | 
| 6 | 
            +
            met:
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            1. Redistributions of source code must retain the above copyright
         | 
| 9 | 
            +
            notice, this list of conditions and the following disclaimer.
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            2. Redistributions in binary form must reproduce the above copyright
         | 
| 12 | 
            +
            notice, this list of conditions and the following disclaimer in the
         | 
| 13 | 
            +
            documentation and/or other materials provided with the distribution.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            3. Neither the name of the copyright holder nor the names of its
         | 
| 16 | 
            +
            contributors may be used to endorse or promote products derived from
         | 
| 17 | 
            +
            this software without specific prior written permission.
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
         | 
| 20 | 
            +
            "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
         | 
| 21 | 
            +
            LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
         | 
| 22 | 
            +
            A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
         | 
| 23 | 
            +
            HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
         | 
| 24 | 
            +
            SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
         | 
| 25 | 
            +
            LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
         | 
| 26 | 
            +
            DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
         | 
| 27 | 
            +
            THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
         | 
| 28 | 
            +
            (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
         | 
| 29 | 
            +
            OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         | 
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,229 @@ | |
| 1 | 
            +
            # khipu
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            [khipu - Yo pago, Yo cobro](https://khipu.com)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Gema Ruby para utilizar los servicios de Khipu.com
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            Versión Biblioteca: 1.3.0
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            Versión API Khipu: 1.3
         | 
| 10 | 
            +
            Versión API de notificación: 1.2
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            La documentación de Khipu.com se puede ver desde aquí: [https://khipu.com/page/api](https://khipu.com/page/api)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            ## Uso
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            Primero instalar la gema ruby
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            ```Bash
         | 
| 19 | 
            +
                $ gem install khipu
         | 
| 20 | 
            +
            ```
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            Luego debes incluir la gema desde tus scripts Ruby usando _require 'khipu'_
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            ## Operaciones
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            Esta biblioteca implementa los siguientes servicios de khipu:
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            1. Obtener listado de bancos
         | 
| 29 | 
            +
            2. Crear cobros y enviarlos por mail. 
         | 
| 30 | 
            +
            3. Crear una página de Pago.
         | 
| 31 | 
            +
            4. Crear una página de Pago (autenticado).
         | 
| 32 | 
            +
            5. Crear un pago y obtener us URL.
         | 
| 33 | 
            +
            6. Crear un pago y obtener us URL (autenticado).
         | 
| 34 | 
            +
            7. Recibir y validar la notificación de un pago.
         | 
| 35 | 
            +
            8. Verificar el estado de una cuenta de cobro.
         | 
| 36 | 
            +
            9. Verificar el estado de un pago.
         | 
| 37 | 
            +
            10. Marcar un pago como pagado.
         | 
| 38 | 
            +
            11. Marcar un cobro como expirado.
         | 
| 39 | 
            +
            12. Marcar un pago como rechazado.
         | 
| 40 | 
            +
             | 
| 41 | 
            +
             | 
| 42 | 
            +
            ### 1) Obtener listado de bancos.
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            Este servicio entrega un mapa con el listado de los bancos disponibles para efectuar un pago a un cobrador determinado.
         | 
| 45 | 
            +
            Cada banco tiene su identificador, un nombre, el monto mínimo que se puede transferir desde él y un mensaje con
         | 
| 46 | 
            +
            información importante.
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            ```Ruby
         | 
| 49 | 
            +
                begin 
         | 
| 50 | 
            +
                    banks = Khipu.create_khipu_api(ID_DEL_COBRADOR, 'SECRET_DEL_COBRADOR').receiver_banks
         | 
| 51 | 
            +
                rescue Khipu::ApiError  => error
         | 
| 52 | 
            +
                    puts error.type
         | 
| 53 | 
            +
                    puts error.message
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
            ```
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            ### 2) Crear cobros y enviarlos por mail.
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            Este servicio entrega un mapa que contiene el identificador del cobro generado así como una lista de los pagos asociados
         | 
| 60 | 
            +
            a este cobro. Por cada pago se tiene el ID, el correo asociado y la URL en khipu para pagar.
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            ```Ruby
         | 
| 63 | 
            +
                begin 
         | 
| 64 | 
            +
                    service = Khipu.create_khipu_api(ID_DEL_COBRADOR, SECRET_DEL_COBRADOR)
         | 
| 65 | 
            +
                    map = service.create_email({subject: 'Un cobro desde Ruby', amount: '10', destinataries: [ {name: "John Doe", email: "john.doe@gmail.com", amount: "1000"}, {name: "Jane Dow", email: "jane.dow@gmail.com", amount: "1000"}], pay_directly: true, send_emails: true})
         | 
| 66 | 
            +
                rescue Khipu::ApiError => error
         | 
| 67 | 
            +
                    puts error.type
         | 
| 68 | 
            +
                    puts error.message
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
            ```
         | 
| 71 | 
            +
            *Importante*: El parámetro _destinataries_ es un mapa Ruby y no un string. Internamente es convertido a un string JSON
         | 
| 72 | 
            +
             | 
| 73 | 
            +
            ### 3) Crear una página de Pago.
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            Este ejemplo genera un archivo .html con un formulario de pago en khipu.
         | 
| 76 | 
            +
             | 
| 77 | 
            +
            ```Ruby
         | 
| 78 | 
            +
                File.open('form.html', 'w') { |file|
         | 
| 79 | 
            +
                    service = Khipu.create_html_helper(2, 'e40ac9591200b2ec9277cd1c795af82d618cf78e')
         | 
| 80 | 
            +
                    form = service.create_payment_form({subject: 'Un cobro desde Ruby', body: 'El cuerpo del cobro', amount: "1000", email: 'john.doe@gmail.com'})
         | 
| 81 | 
            +
                    file.write(form)
         | 
| 82 | 
            +
                }
         | 
| 83 | 
            +
            ```
         | 
| 84 | 
            +
             | 
| 85 | 
            +
            ### 4) Crear una página de Pago (autenticado).
         | 
| 86 | 
            +
             | 
| 87 | 
            +
            Para crear una página de pago que solo permita pagar usando una cuenta asociada a un RUT en particular debes usar el
         | 
| 88 | 
            +
            mismo servicio del punto anterior indicando el RUT en el parámetro _payer_username_
         | 
| 89 | 
            +
             | 
| 90 | 
            +
            ```Ruby
         | 
| 91 | 
            +
                File.open('form.html', 'w') { |file|
         | 
| 92 | 
            +
                    service = Khipu.create_html_helper(2, 'e40ac9591200b2ec9277cd1c795af82d618cf78e')
         | 
| 93 | 
            +
                    form = service.create_payment_form({subject: 'Un cobro desde Ruby', body: 'El cuerpo del cobro', amount: "1000", email: 'john.doe@gmail.com', payer_username: '128723463'})
         | 
| 94 | 
            +
                    file.write(form)
         | 
| 95 | 
            +
                }
         | 
| 96 | 
            +
            ```
         | 
| 97 | 
            +
             | 
| 98 | 
            +
            ### 5) Crear un pago y obtener su URL.
         | 
| 99 | 
            +
             | 
| 100 | 
            +
            Este servicio entrega un mapa que contiene el identificador de un pago generado, su URL en khipu y la URL para iniciar
         | 
| 101 | 
            +
            el pago desde un dispositivo móvil.
         | 
| 102 | 
            +
             | 
| 103 | 
            +
            ```Ruby
         | 
| 104 | 
            +
                begin 
         | 
| 105 | 
            +
                    service = Khipu.create_khipu_api(ID_DEL_COBRADOR, SECRET_DEL_COBRADOR)
         | 
| 106 | 
            +
                    map = service.create_payment_url({subject: 'Un cobro desde Ruby', body: 'El cuerpo del cobro', amount: "1000", email: 'john.doe@gmail.com'})
         | 
| 107 | 
            +
                rescue Khipu::ApiError => error
         | 
| 108 | 
            +
                    puts error.type
         | 
| 109 | 
            +
                    puts error.message
         | 
| 110 | 
            +
                end
         | 
| 111 | 
            +
            ```
         | 
| 112 | 
            +
            ### 6) Crear un pago y obtener su URL (autenticado).
         | 
| 113 | 
            +
             | 
| 114 | 
            +
            Este servicio es idéntico al anterior pero usando el parámetro _payer_username_ se fuerza que la cuenta corriente usada
         | 
| 115 | 
            +
            para pagar debe estar asociada al RUT indicado.
         | 
| 116 | 
            +
             | 
| 117 | 
            +
            ```Ruby
         | 
| 118 | 
            +
                begin
         | 
| 119 | 
            +
                    service = Khipu.create_khipu_api(ID_DEL_COBRADOR, SECRET_DEL_COBRADOR)
         | 
| 120 | 
            +
                    map = service.create_authenticated_payment_url({subject: 'Un cobro desde Ruby', body: 'El cuerpo del cobro', amount: "1000", email: 'john.doe@gmail.com', payer_username: '128723463'})
         | 
| 121 | 
            +
                rescue Khipu::ApiError => error
         | 
| 122 | 
            +
                    puts error.type
         | 
| 123 | 
            +
                    puts error.message
         | 
| 124 | 
            +
                end
         | 
| 125 | 
            +
            ```
         | 
| 126 | 
            +
            Se puede obtener una
         | 
| 127 | 
            +
            ### 7) Validar la notificación de un pago.
         | 
| 128 | 
            +
             | 
| 129 | 
            +
            Este ejemplo contacta a khipu para validar los datos de una transacción. Para usar
         | 
| 130 | 
            +
            este servicio no es necesario configurar el SECRET del cobrador. Se retorna true si la información del la notificación
         | 
| 131 | 
            +
            es válida. En este ejemplo los parámetros se configuran a mano, pero en producción los datos deben obtenerse desde
         | 
| 132 | 
            +
            el _request html_.
         | 
| 133 | 
            +
             | 
| 134 | 
            +
            ```Ruby
         | 
| 135 | 
            +
                begin 
         | 
| 136 | 
            +
                    service = Khipu.create_khipu_api(ID_DEL_COBRADOR, SECRET_DEL_COBRADOR)
         | 
| 137 | 
            +
                    params = {api_version: '1.2', 
         | 
| 138 | 
            +
                            notification_id: 'aq1td2jl2uen', 
         | 
| 139 | 
            +
                            subject: 'Motivo de prueba', 
         | 
| 140 | 
            +
                            amount: 12575,
         | 
| 141 | 
            +
                            currency: 'CLP', 
         | 
| 142 | 
            +
                            transaction_id: 'FTEEE5SWWO', 
         | 
| 143 | 
            +
                            payer_email: 'john.doe@gmail.com',
         | 
| 144 | 
            +
                            custom: 'Custom info', 
         | 
| 145 | 
            +
                            notification_signature: 'j8kPBHaPNy3PkCh...hhLvQbenpGjA=='
         | 
| 146 | 
            +
                    }
         | 
| 147 | 
            +
                    valid = service.verify_payment_notification(params)
         | 
| 148 | 
            +
                rescue Khipu::ApiError => error
         | 
| 149 | 
            +
                    puts error.type
         | 
| 150 | 
            +
                    puts error.message
         | 
| 151 | 
            +
                end
         | 
| 152 | 
            +
            ```
         | 
| 153 | 
            +
             | 
| 154 | 
            +
             | 
| 155 | 
            +
            ### 8) Verificar el estado de una cuenta de cobro.
         | 
| 156 | 
            +
             | 
| 157 | 
            +
            Este servicio permite consultar el estado de una cuenta khipu. Se devuelve un mapa que indica si esta cuenta está
         | 
| 158 | 
            +
            habilitada para cobrar y el tipo de cuenta (desarrollo o producción).
         | 
| 159 | 
            +
             | 
| 160 | 
            +
            ```Ruby
         | 
| 161 | 
            +
                begin 
         | 
| 162 | 
            +
                    service = Khipu.create_khipu_api(ID_DEL_COBRADOR, SECRET_DEL_COBRADOR)
         | 
| 163 | 
            +
                    map = service.receiver_status; 
         | 
| 164 | 
            +
                rescue Khipu::ApiError => error
         | 
| 165 | 
            +
                    puts error.type
         | 
| 166 | 
            +
                    puts error.message
         | 
| 167 | 
            +
                end
         | 
| 168 | 
            +
            ```
         | 
| 169 | 
            +
             
         | 
| 170 | 
            +
            ### 9) Verificar el estado de un pago.
         | 
| 171 | 
            +
             | 
| 172 | 
            +
            Este servició sirve para verificar el estado de un pago.
         | 
| 173 | 
            +
             | 
| 174 | 
            +
            ```Ruby
         | 
| 175 | 
            +
                begin 
         | 
| 176 | 
            +
                    service = Khipu.create_khipu_api(ID_DEL_COBRADOR, SECRET_DEL_COBRADOR)
         | 
| 177 | 
            +
                    map = service.payment_status({payment_id: '9fnsggqqi8ho'})
         | 
| 178 | 
            +
                rescue Khipu::ApiError  => error
         | 
| 179 | 
            +
                    puts error.type
         | 
| 180 | 
            +
                    puts error.message
         | 
| 181 | 
            +
                end
         | 
| 182 | 
            +
            ```
         | 
| 183 | 
            +
             | 
| 184 | 
            +
            ### 10) Marcar un cobro como pagado.
         | 
| 185 | 
            +
             | 
| 186 | 
            +
            Este servicio permite marcar un cobro como pagado. Si el pagador paga por un método alternativo a khipu, el cobrador
         | 
| 187 | 
            +
            puede marcar este cobro como saldado.
         | 
| 188 | 
            +
             | 
| 189 | 
            +
            ```Ruby
         | 
| 190 | 
            +
                begin 
         | 
| 191 | 
            +
                    service = Khipu.create_khipu_api(ID_DEL_COBRADOR, SECRET_DEL_COBRADOR)
         | 
| 192 | 
            +
                    service.set_paid_by_receiver({payment_id: '54dhfsch6avd'});
         | 
| 193 | 
            +
                rescue Khipu::ApiError => error
         | 
| 194 | 
            +
                    puts error.type
         | 
| 195 | 
            +
                    puts error.message
         | 
| 196 | 
            +
                end
         | 
| 197 | 
            +
            ```
         | 
| 198 | 
            +
             | 
| 199 | 
            +
            ### 11) Marcar un cobro como expirado.
         | 
| 200 | 
            +
             | 
| 201 | 
            +
            Este servicio permite adelantar la expiración del cobro. Se puede adjuntar un texto que será desplegado a la gente que
         | 
| 202 | 
            +
            trate de ir a pagar.
         | 
| 203 | 
            +
             | 
| 204 | 
            +
             | 
| 205 | 
            +
            ```Ruby
         | 
| 206 | 
            +
                begin 
         | 
| 207 | 
            +
                    service = Khipu.create_khipu_api(ID_DEL_COBRADOR, SECRET_DEL_COBRADOR)
         | 
| 208 | 
            +
                    service.set_bill_expired({bill_id: 'udmEe', text: 'Plazo vencido'})
         | 
| 209 | 
            +
                rescue Khipu::ApiError => error
         | 
| 210 | 
            +
                    puts error.type
         | 
| 211 | 
            +
                    puts error.message
         | 
| 212 | 
            +
                end
         | 
| 213 | 
            +
            ```
         | 
| 214 | 
            +
             | 
| 215 | 
            +
            ### 12) Marcar un cobro como rechazado.
         | 
| 216 | 
            +
             | 
| 217 | 
            +
            Este servicio permite rechazar pago con el fin de inhabilitarlo. Permite indicar la razón por la que el pagador rechaza
         | 
| 218 | 
            +
            saldar este pago:
         | 
| 219 | 
            +
             | 
| 220 | 
            +
             | 
| 221 | 
            +
            ```Ruby
         | 
| 222 | 
            +
                begin 
         | 
| 223 | 
            +
                    service = Khipu.create_khipu_api(ID_DEL_COBRADOR, SECRET_DEL_COBRADOR)
         | 
| 224 | 
            +
                    service.set_rejected_by_payer({payment_id: '0pk7xfgocry4', text: 'El pago no corresponde'});
         | 
| 225 | 
            +
                rescue Khipu::ApiError => error
         | 
| 226 | 
            +
                    puts error.type
         | 
| 227 | 
            +
                    puts error.message
         | 
| 228 | 
            +
                end
         | 
| 229 | 
            +
            ```
         | 
    
        data/Rakefile
    ADDED
    
    
    
        data/khipu.gemspec
    ADDED
    
    | @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            lib = File.expand_path('../lib', __FILE__)
         | 
| 3 | 
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 4 | 
            +
            require 'khipu/version'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            Gem::Specification.new do |spec|
         | 
| 7 | 
            +
              spec.name          = "khipu"
         | 
| 8 | 
            +
              spec.version       = Khipu::VERSION
         | 
| 9 | 
            +
              spec.authors       = ["Alex Lorca"]
         | 
| 10 | 
            +
              spec.email         = ["alex.lorca@khipu.com"]
         | 
| 11 | 
            +
              spec.description   = "A wrapper for khipu's web API"
         | 
| 12 | 
            +
              spec.summary       = "A wrapper for khipu's web API"
         | 
| 13 | 
            +
              spec.homepage      = "https://github.com/khipu/lib-ruby"
         | 
| 14 | 
            +
              spec.license       = "BSD"
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              spec.files         = `git ls-files`.split($/)
         | 
| 17 | 
            +
              spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
         | 
| 18 | 
            +
              spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
         | 
| 19 | 
            +
              spec.require_paths = ["lib"]
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              spec.required_ruby_version = ">= 1.9"
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              spec.add_development_dependency "bundler", "~> 1.3"
         | 
| 24 | 
            +
              spec.add_development_dependency "rake"
         | 
| 25 | 
            +
              spec.add_development_dependency "rspec"
         | 
| 26 | 
            +
            end
         | 
    
        data/lib/khipu/const.rb
    ADDED
    
    | @@ -0,0 +1,59 @@ | |
| 1 | 
            +
            module Khipu
         | 
| 2 | 
            +
              CERT_PROD = %q{-----BEGIN CERTIFICATE-----
         | 
| 3 | 
            +
            MIIFuDCCBSGgAwIBAgIQHCWU8WfzVpZq9iYPMgYpVzANBgkqhkiG9w0BAQUFADCB
         | 
| 4 | 
            +
            0DEUMBIGA1UEChMLRS1TaWduIFMuQS4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0
         | 
| 5 | 
            +
            IE5ldHdvcmsxODA2BgNVBAsTL1Rlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy5l
         | 
| 6 | 
            +
            LXNpZ24uY2wvcnBhIChjKTA1MTwwOgYDVQQDEzNFLVNpZ24gU0MgQ2xhc3MgMiBD
         | 
| 7 | 
            +
            b25zdW1lciBJbmRpdmlkdWFsIFN1YnNjcmliZXIgQ0ExHzAdBgkqhkiG9w0BCQEW
         | 
| 8 | 
            +
            EGUtc2lnbkBlLXNpZ24uY2wwHhcNMTIxMTA3MDAwMDAwWhcNMTMxMTA3MjM1OTU5
         | 
| 9 | 
            +
            WjCCAQgxMDAuBgNVBAsTJ1Rlcm1zIG9mIHVzZSBhdCB3d3cuZS1zaWduLmNsL3Jw
         | 
| 10 | 
            +
            YSBDKDA0KTElMCMGA1UECxMcQXV0aGVudGljYXRlZCBieSBFLVNpZ24gUy5BLjEn
         | 
| 11 | 
            +
            MCUGA1UECxMeTWVtYmVyLCBWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMRswGQYDVQQL
         | 
| 12 | 
            +
            ExJEaWdpdGFsIElEIENsYXNzIDIxGDAWBgNVBAsUD1JVVCAtIDkxMjM4NDUtNDEl
         | 
| 13 | 
            +
            MCMGA1UEAxMcUm9iZXJ0byBBbmRyZXMgT3Bhem8gR2F6bXVyaTEmMCQGCSqGSIb3
         | 
| 14 | 
            +
            DQEJARYXcm9iZXJ0by5vcGF6b0BraGlwdS5jb20wggEiMA0GCSqGSIb3DQEBAQUA
         | 
| 15 | 
            +
            A4IBDwAwggEKAoIBAQC4xI/f6C/5V/KsIAQY3G2ExoqIb8NoM7czRw9UNdx/OEiL
         | 
| 16 | 
            +
            QJfqJjx1gVkcZxHqcWT6DENuf7H2LyYvzXOfeQgN5Zw8FCdIxjoF00AOIf3YDLdG
         | 
| 17 | 
            +
            0IXoiRuZWPh9JkbGyl/tSd/fJWSh12GQAUE0m0YYMNHGiNPqiZ3jJEUgNWKjfO2D
         | 
| 18 | 
            +
            xMqTGrujDnA3qF/2SiBrWRj5XyZCIYumrHWKGQnvmd6uaH4SOyaPc1Jl8byqfzg6
         | 
| 19 | 
            +
            GlHX2hWyVJ2Tc+GHxAiSm8RzUfSAfgCbUm+/8gX0uDlGA7dqaa9FIZh7RWBdN4Nn
         | 
| 20 | 
            +
            Dd9XHEOtXnBVL6mFzut57eAwEHz+a6tv2E2yy/GJAgMBAAGjggHSMIIBzjAiBgNV
         | 
| 21 | 
            +
            HREEGzAZoBcGCCsGAQQBwQEBoAsWCTkxMjM4NDUtNDAJBgNVHRMEAjAAMAsGA1Ud
         | 
| 22 | 
            +
            DwQEAwIFoDCBmQYDVR0gBIGRMIGOMIGLBgtghkgBhvhFAQcXAjB8MDEGCCsGAQUF
         | 
| 23 | 
            +
            BwIBFiVodHRwczovL3d3dy5lLXNpZ24uY2wvcmVwb3NpdG9yaW8uaHRtMEcGCCsG
         | 
| 24 | 
            +
            AQUFBwICMDsaOUNlcnRpZmljYWRvIHBhcmEgdXNvIFRyaWJ1dGFyaW8sIENvbWVy
         | 
| 25 | 
            +
            Y2lvLCBQYWdvcyB5IE90cm9zLjAjBgNVHRIEHDAaoBgGCCsGAQQBwQECoAwWCjk5
         | 
| 26 | 
            +
            NTUxNzQwLUswTQYDVR0fBEYwRDBCoECgPoY8aHR0cDovL29uc2l0ZWNybC52ZXJp
         | 
| 27 | 
            +
            c2lnbi5jb20vRVNpZ25TQUNTQ0NsYXNzMi9MYXRlc3RDUkwuY3JsMDsGCCsGAQUF
         | 
| 28 | 
            +
            BwEBBC8wLTArBggrBgEFBQcwAYYfaHR0cDovL29uc2l0ZS1vY3NwLnZlcmlzaWdu
         | 
| 29 | 
            +
            LmNvbTAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwEQYJYIZIAYb4QgEB
         | 
| 30 | 
            +
            BAQDAgeAMBEGCmCGSAGG+EUBBgkEAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAFiXQz
         | 
| 31 | 
            +
            K9TrKWkJH3is2H/QI8gynHQV71kvmSUnRgPk5TdXzd6EDhbaQMC3pCdwhpKKUfFo
         | 
| 32 | 
            +
            0Ky8wtkagE8jdCRkpDfGpnhINfJZW9HH3gKe2zFckynPZcV5fsVM1tQzWQNBPaFf
         | 
| 33 | 
            +
            scJQlyZrC17dCDWkJ2op67BRjp97skB1SUWtRw==
         | 
| 34 | 
            +
            -----END CERTIFICATE-----}
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              CERT_DEV = %q{-----BEGIN CERTIFICATE-----
         | 
| 37 | 
            +
            MIIDszCCApsCBFA88VcwDQYJKoZIhvcNAQEFBQAwgZ0xIDAeBgkqhkiG9w0BCQEW
         | 
| 38 | 
            +
            EXJvYmVydG9Acm9wYXpvLmNsMQswCQYDVQQGEwJDTDERMA8GA1UECAwIU2FudGlh
         | 
| 39 | 
            +
            Z28xCzAJBgNVBAcMAlJNMRIwEAYDVQQKDAlLaGlwdS5jb20xGDAWBgNVBAsMD0dl
         | 
| 40 | 
            +
            cmVudGUgR2VuZXJhbDEeMBwGA1UEAwwVUm9iZXJ0byBPcGF6byBHYXptdXJpMB4X
         | 
| 41 | 
            +
            DTEyMDgyODE2MjcwM1oXDTEzMDgyODE2MjcwM1owgZ0xIDAeBgkqhkiG9w0BCQEW
         | 
| 42 | 
            +
            EXJvYmVydG9Acm9wYXpvLmNsMQswCQYDVQQGEwJDTDERMA8GA1UECAwIU2FudGlh
         | 
| 43 | 
            +
            Z28xCzAJBgNVBAcMAlJNMRIwEAYDVQQKDAlLaGlwdS5jb20xGDAWBgNVBAsMD0dl
         | 
| 44 | 
            +
            cmVudGUgR2VuZXJhbDEeMBwGA1UEAwwVUm9iZXJ0byBPcGF6byBHYXptdXJpMIIB
         | 
| 45 | 
            +
            IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk+0IYrfbAPSRSX8u3+js786J
         | 
| 46 | 
            +
            QTMXGS52LUFHOKXokQbqfcbPs9qwBDr4NeRbM3GQ8CRLLM9PKenHbd93ErpY4GDC
         | 
| 47 | 
            +
            CWZPU9RA4nFgJa/pJzFEf74dR0tQOnEdEDwCdlAp7EkVFIUnweSDG0QG9Dedvn/J
         | 
| 48 | 
            +
            tlHMRM0NXQSq6NxFPzjTyK4/J5g86V9LPEt6h+TpQACKxGxKa9cDdt6n8wDhskwV
         | 
| 49 | 
            +
            V6xiwkq+j+tNh5+DIdKstceG8UulgdpgTt9r7kr9FVwL1L3ugJ4zK1fGYbTwPQRu
         | 
| 50 | 
            +
            H9C0y7vZ/Mjm/osv9BAm0r57ywVgPU6af2yrTMhMkuCkMrIq4qW0XDiCTiso8QID
         | 
| 51 | 
            +
            AQABMA0GCSqGSIb3DQEBBQUAA4IBAQCO6do2tYvE5/nLYnPXQbpUhhJLvZbJd+Nl
         | 
| 52 | 
            +
            jLUlju2yzgNLFA3g19t9uKxKRG497//WdxHoa3lAPnY8IO+DgKp5dOMcKLopz+AX
         | 
| 53 | 
            +
            jsElzCQxcPNqlYwGQgEDDm9q0WXs1Dg22y0Af1oR5Lx9XR1xWsw4z/6YEDUJRa7D
         | 
| 54 | 
            +
            fAUIip+ocbMykuUvnrNU/wUDRv8VbsIoMr+1CK3pKACSUuB8ZhYfRUjgHEXKh4O5
         | 
| 55 | 
            +
            I/hKy49jGW/9i5GOTEGGzOvHm2CIrpBPFWfKSJLjvLtYWbBuCyKK5+FsP4wuN8Rv
         | 
| 56 | 
            +
            yLM1MDg00bd5M5MmTA1FFNGiGUqpfo7z+kcqRFOJqWm7bmaDvZVJ
         | 
| 57 | 
            +
            -----END CERTIFICATE-----}
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            end
         | 
| @@ -0,0 +1,53 @@ | |
| 1 | 
            +
            module Khipu
         | 
| 2 | 
            +
              class HtmlHelper < KhipuService
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                def initialize(receiver_id, secret)
         | 
| 5 | 
            +
                  super(receiver_id, secret)
         | 
| 6 | 
            +
                end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def create_payment_form(args, button = Khipu::FORM_BUTTONS['50x25'])
         | 
| 9 | 
            +
                  endpoint_url = Khipu::API_URL + 'createPaymentPage'
         | 
| 10 | 
            +
                  check_arguments(args, [:subject, :amount])
         | 
| 11 | 
            +
                  params = {
         | 
| 12 | 
            +
                      receiver_id: @receiver_id,
         | 
| 13 | 
            +
                      subject: args[:subject],
         | 
| 14 | 
            +
                      body: args[:body] || '',
         | 
| 15 | 
            +
                      amount: args[:amount]
         | 
| 16 | 
            +
                  }
         | 
| 17 | 
            +
                  payer_username = ''
         | 
| 18 | 
            +
                  if args[:payer_username]
         | 
| 19 | 
            +
                    payer_username = %Q{\n<input type="hidden" name="payer_username" value="#{args[:payer_username]}"/>}
         | 
| 20 | 
            +
                    params[:payer_username] = args[:payer_username]
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                  params.merge!({
         | 
| 23 | 
            +
                      payer_email: args[:payer_email] || '',
         | 
| 24 | 
            +
                      bank_id: args[:bank_id] || '',
         | 
| 25 | 
            +
                      expires_date: args[:expires_date] || '',
         | 
| 26 | 
            +
                      transaction_id: args[:transaction_id] || '',
         | 
| 27 | 
            +
                      custom: args[:custom] || '',
         | 
| 28 | 
            +
                      notify_url: args[:notify_url] || '',
         | 
| 29 | 
            +
                      return_url: args[:return_url] || '',
         | 
| 30 | 
            +
                      cancel_url: args[:cancel_url] || '',
         | 
| 31 | 
            +
                      picture_url: args[:picture_url] || '',
         | 
| 32 | 
            +
                  })
         | 
| 33 | 
            +
                  params[:hash] = hmac_sha256(@secret, concatenated(params))
         | 
| 34 | 
            +
                  %Q{<form action="#{endpoint_url}" method="post">
         | 
| 35 | 
            +
            <input type="hidden" name="receiver_id" value="#{params[:receiver_id]}">
         | 
| 36 | 
            +
            <input type="hidden" name="subject" value="#{params[:subject]}"/>
         | 
| 37 | 
            +
            <input type="hidden" name="body" value="#{params[:body]}">
         | 
| 38 | 
            +
            <input type="hidden" name="amount" value="#{params[:amount]}">#{payer_username}
         | 
| 39 | 
            +
            <input type="hidden" name="notify_url" value="#{params[:notify_url]}"/>
         | 
| 40 | 
            +
            <input type="hidden" name="return_url" value="#{params[:return_url]}"/>
         | 
| 41 | 
            +
            <input type="hidden" name="cancel_url" value="#{params[:cancel_url]}"/>
         | 
| 42 | 
            +
            <input type="hidden" name="custom" value="#{params[:custom]}">
         | 
| 43 | 
            +
            <input type="hidden" name="transaction_id" value="#{params[:transaction_id]}">
         | 
| 44 | 
            +
            <input type="hidden" name="payer_email" value="#{params[:payer_email]}">
         | 
| 45 | 
            +
            <input type="hidden" name="expires_date" value="#{params[:expires_date]}">
         | 
| 46 | 
            +
            <input type="hidden" name="bank_id" value="#{params[:bank_id]}">
         | 
| 47 | 
            +
            <input type="hidden" name="picture_url" value="#{params[:picture_url]}">
         | 
| 48 | 
            +
            <input type="hidden" name="hash" value="#{params[:hash]}">
         | 
| 49 | 
            +
            <input type="image" name="submit" src="#{button}">
         | 
| 50 | 
            +
            </form>}
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
            end
         | 
| @@ -0,0 +1,184 @@ | |
| 1 | 
            +
            require 'json'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Khipu
         | 
| 4 | 
            +
              class KhipuApiEndpoint < KhipuService
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def initialize(receiver_id, secret)
         | 
| 7 | 
            +
                  super(receiver_id, secret)
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def execute(endpoint, params, add_hash = true, json_response = true)
         | 
| 11 | 
            +
                  post_params = params.clone
         | 
| 12 | 
            +
                  if add_hash
         | 
| 13 | 
            +
                    post_params['hash'] = hmac_sha256(@secret, concatenated(params))
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                  post(endpoint, post_params, json_response)
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def payment_status(args)
         | 
| 19 | 
            +
                  endpoint = 'paymentStatus'
         | 
| 20 | 
            +
                  check_arguments(args, [:payment_id])
         | 
| 21 | 
            +
                  params = {
         | 
| 22 | 
            +
                      receiver_id: @receiver_id,
         | 
| 23 | 
            +
                      payment_id: args[:payment_id]
         | 
| 24 | 
            +
                  }
         | 
| 25 | 
            +
                  execute(endpoint, params)
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def create_payment_url(args)
         | 
| 29 | 
            +
                  endpoint = 'createPaymentURL'
         | 
| 30 | 
            +
                  check_arguments(args, [:subject, :amount])
         | 
| 31 | 
            +
                  params = {
         | 
| 32 | 
            +
                      receiver_id: @receiver_id,
         | 
| 33 | 
            +
                      subject: args[:subject],
         | 
| 34 | 
            +
                      body: args[:body] || '',
         | 
| 35 | 
            +
                      amount: args[:amount],
         | 
| 36 | 
            +
                      payer_email: args[:payer_email] || '',
         | 
| 37 | 
            +
                      bank_id: args[:bank_id] || '',
         | 
| 38 | 
            +
                      expires_date: args[:expires_date] || '',
         | 
| 39 | 
            +
                      transaction_id: args[:transaction_id] || '',
         | 
| 40 | 
            +
                      custom: args[:custom] || '',
         | 
| 41 | 
            +
                      notify_url: args[:notify_url] || '',
         | 
| 42 | 
            +
                      return_url: args[:return_url] || '',
         | 
| 43 | 
            +
                      cancel_url: args[:cancel_url] || '',
         | 
| 44 | 
            +
                      picture_url: args[:picture_url] || ''
         | 
| 45 | 
            +
                  }
         | 
| 46 | 
            +
                  resp = execute(endpoint, params)
         | 
| 47 | 
            +
                  resp_items = %w(id url mobile-url)
         | 
| 48 | 
            +
                  resp.select{|key, value| resp_items.include?(key)}
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                def create_authenticated_payment_url(args)
         | 
| 52 | 
            +
                  endpoint = 'createAuthenticatedPaymentURL'
         | 
| 53 | 
            +
                  check_arguments(args, [:subject, :amount, :payer_username])
         | 
| 54 | 
            +
                  params = {
         | 
| 55 | 
            +
                      receiver_id: @receiver_id,
         | 
| 56 | 
            +
                      subject: args[:subject],
         | 
| 57 | 
            +
                      body: args[:body] || '',
         | 
| 58 | 
            +
                      amount: args[:amount],
         | 
| 59 | 
            +
                      payer_username: args[:payer_username],
         | 
| 60 | 
            +
                      payer_email: args[:payer_email] || '',
         | 
| 61 | 
            +
                      bank_id: args[:bank_id] || '',
         | 
| 62 | 
            +
                      expires_date: args[:expires_date] || '',
         | 
| 63 | 
            +
                      transaction_id: args[:transaction_id] || '',
         | 
| 64 | 
            +
                      custom: args[:custom] || '',
         | 
| 65 | 
            +
                      notify_url: args[:notify_url] || '',
         | 
| 66 | 
            +
                      return_url: args[:return_url] || '',
         | 
| 67 | 
            +
                      cancel_url: args[:cancel_url] || '',
         | 
| 68 | 
            +
                      picture_url: args[:picture_url] || ''
         | 
| 69 | 
            +
                  }
         | 
| 70 | 
            +
                  resp = execute(endpoint, params)
         | 
| 71 | 
            +
                  resp_items = %w(id url mobile-url)
         | 
| 72 | 
            +
                  resp.select{|key, value| resp_items.include?(key)}
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                def create_email(args)
         | 
| 76 | 
            +
                  endpoint = 'createEmail'
         | 
| 77 | 
            +
                  check_arguments(args, [:subject, :destinataries, :pay_directly, :send_emails])
         | 
| 78 | 
            +
                  params = {
         | 
| 79 | 
            +
                      receiver_id: @receiver_id,
         | 
| 80 | 
            +
                      subject: args[:subject],
         | 
| 81 | 
            +
                      body: args[:body] || '',
         | 
| 82 | 
            +
                      destinataries: args[:destinataries].to_json,
         | 
| 83 | 
            +
                      pay_directly: args[:pay_directly],
         | 
| 84 | 
            +
                      send_emails: args[:send_emails],
         | 
| 85 | 
            +
                      expires_date: args[:expires_date] || '',
         | 
| 86 | 
            +
                      transaction_id: args[:transaction_id] || '',
         | 
| 87 | 
            +
                      custom: args[:custom] || '',
         | 
| 88 | 
            +
                      notify_url: args[:notify_url] || '',
         | 
| 89 | 
            +
                      return_url: args[:return_url] || '',
         | 
| 90 | 
            +
                      cancel_url: args[:cancel_url] || '',
         | 
| 91 | 
            +
                      picture_url: args[:picture_url] || ''
         | 
| 92 | 
            +
                  }
         | 
| 93 | 
            +
                  execute(endpoint, params)
         | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                def receiver_banks
         | 
| 97 | 
            +
                  endpoint = 'receiverBanks'
         | 
| 98 | 
            +
                  params = {
         | 
| 99 | 
            +
                      receiver_id: @receiver_id
         | 
| 100 | 
            +
                  }
         | 
| 101 | 
            +
                  resp = execute(endpoint, params)
         | 
| 102 | 
            +
                  resp_items = %w(id name message min-amount)
         | 
| 103 | 
            +
                  resp['banks'].map{|item| item.select{|key, value| resp_items.include?(key)} }
         | 
| 104 | 
            +
                end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                def receiver_status
         | 
| 107 | 
            +
                  endpoint = 'receiverStatus'
         | 
| 108 | 
            +
                  params = {
         | 
| 109 | 
            +
                      receiver_id: @receiver_id,
         | 
| 110 | 
            +
                  }
         | 
| 111 | 
            +
                  execute(endpoint, params)
         | 
| 112 | 
            +
                end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                def set_bill_expired(args)
         | 
| 115 | 
            +
                  endpoint = 'setBillExpired'
         | 
| 116 | 
            +
                  check_arguments(args, [:bill_id])
         | 
| 117 | 
            +
                  params = {
         | 
| 118 | 
            +
                      receiver_id: @receiver_id,
         | 
| 119 | 
            +
                      bill_id: args[:bill_id],
         | 
| 120 | 
            +
                      text: args[:text] || ''
         | 
| 121 | 
            +
                  }
         | 
| 122 | 
            +
                  execute(endpoint, params)
         | 
| 123 | 
            +
                end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                def set_paid_by_receiver(args)
         | 
| 126 | 
            +
                  endpoint = 'setPaidByReceiver'
         | 
| 127 | 
            +
                  check_arguments(args, [:payment_id])
         | 
| 128 | 
            +
                  params = {
         | 
| 129 | 
            +
                      receiver_id: @receiver_id,
         | 
| 130 | 
            +
                      payment_id: args[:payment_id],
         | 
| 131 | 
            +
                  }
         | 
| 132 | 
            +
                  execute(endpoint, params)
         | 
| 133 | 
            +
                end
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                def set_rejected_by_payer(args)
         | 
| 136 | 
            +
                  endpoint = 'setRejectedByPayer'
         | 
| 137 | 
            +
                  check_arguments(args, [:payment_id])
         | 
| 138 | 
            +
                  params = {
         | 
| 139 | 
            +
                      receiver_id: @receiver_id,
         | 
| 140 | 
            +
                      payment_id: args[:payment_id],
         | 
| 141 | 
            +
                      text: args[:text] || ''
         | 
| 142 | 
            +
                  }
         | 
| 143 | 
            +
                  execute(endpoint, params)
         | 
| 144 | 
            +
                end
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                def verify_payment_notification(args)
         | 
| 147 | 
            +
                  endpoint = 'verifyPaymentNotification'
         | 
| 148 | 
            +
                  check_arguments(args, [:api_version, :notification_id, :subject, :amount, :payer_email, :notification_signature])
         | 
| 149 | 
            +
                  params = {
         | 
| 150 | 
            +
                      api_version: args[:api_version],
         | 
| 151 | 
            +
                      receiver_id: @receiver_id,
         | 
| 152 | 
            +
                      notification_id: args[:notification_id],
         | 
| 153 | 
            +
                      subject: args[:subject],
         | 
| 154 | 
            +
                      amount: args[:amount],
         | 
| 155 | 
            +
                      currency: args[:currency] || 'CLP',
         | 
| 156 | 
            +
                      transaction_id: args[:transaction_id] || '',
         | 
| 157 | 
            +
                      payer_email: args[:payer_email] || '',
         | 
| 158 | 
            +
                      custom: args[:custom] || '',
         | 
| 159 | 
            +
                      notification_signature: args[:notification_signature]
         | 
| 160 | 
            +
                  }
         | 
| 161 | 
            +
                  resp = execute(endpoint, params, false, false)
         | 
| 162 | 
            +
                  resp == 'VERIFIED'
         | 
| 163 | 
            +
                end
         | 
| 164 | 
            +
             | 
| 165 | 
            +
                def verify_payment_notification_local(args)
         | 
| 166 | 
            +
                  check_arguments(args, [:api_version, :notification_id, :subject, :amount, :payer_email, :notification_signature])
         | 
| 167 | 
            +
                  params = {
         | 
| 168 | 
            +
                      api_version: args[:api_version],
         | 
| 169 | 
            +
                      receiver_id: @receiver_id,
         | 
| 170 | 
            +
                      notification_id: args[:notification_id],
         | 
| 171 | 
            +
                      subject: args[:subject],
         | 
| 172 | 
            +
                      amount: args[:amount],
         | 
| 173 | 
            +
                      currency: args[:currency] || 'CLP',
         | 
| 174 | 
            +
                      transaction_id: args[:transaction_id] || '',
         | 
| 175 | 
            +
                      payer_email: args[:payer_email] || '',
         | 
| 176 | 
            +
                      custom: args[:custom] || '',
         | 
| 177 | 
            +
                  }
         | 
| 178 | 
            +
                  verify_signature(params, args[:notification_signature])
         | 
| 179 | 
            +
                end
         | 
| 180 | 
            +
             | 
| 181 | 
            +
             | 
| 182 | 
            +
             | 
| 183 | 
            +
              end
         | 
| 184 | 
            +
            end
         | 
| @@ -0,0 +1,76 @@ | |
| 1 | 
            +
            require 'net/http'
         | 
| 2 | 
            +
            require 'openssl'
         | 
| 3 | 
            +
            require 'base64'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Khipu
         | 
| 6 | 
            +
              class KhipuService
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                attr_accessor :receiver_id, :secret, :agent
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def initialize(receiver_id, secret)
         | 
| 11 | 
            +
                  @receiver_id = receiver_id
         | 
| 12 | 
            +
                  @secret = secret
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def post(endpoint, params, json_response = true)
         | 
| 16 | 
            +
                  uri = URI(Khipu::API_URL + endpoint)
         | 
| 17 | 
            +
                  http = Net::HTTP.new(uri.host, uri.port)
         | 
| 18 | 
            +
                  http.use_ssl = true
         | 
| 19 | 
            +
                  if Khipu::DEBUG
         | 
| 20 | 
            +
                    http.set_debug_output(Khipu::debug_stream)
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  params['agent'] = "lib-ruby-#{Khipu::VERSION} - #{@agent}" if @agent
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  req = Net::HTTP::Post.new(uri.request_uri, {'User-Agent' => "khipu-ruby-#{Khipu::VERSION}"})
         | 
| 26 | 
            +
                  req.set_form_data(params)
         | 
| 27 | 
            +
                  res = http.request(req)
         | 
| 28 | 
            +
                  if res.code == '400'
         | 
| 29 | 
            +
                    begin
         | 
| 30 | 
            +
                      error = JSON.parse(res.body)
         | 
| 31 | 
            +
                      raise ApiError.new(error['error']['type'], error['error']['message'])
         | 
| 32 | 
            +
                    rescue JSON::ParserError
         | 
| 33 | 
            +
                      raise "Invalid response from endpoint #{uri}"
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
                  elsif res.code != '200'
         | 
| 36 | 
            +
                    raise "Invalid response code #{res.code} endpoint #{uri}"
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                  if Khipu::DEBUG
         | 
| 39 | 
            +
                    Khipu::debug_stream.puts res.body
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                  if json_response
         | 
| 42 | 
            +
                    begin
         | 
| 43 | 
            +
                      JSON.parse(res.body)
         | 
| 44 | 
            +
                    rescue JSON::ParserError
         | 
| 45 | 
            +
                      raise "Invalid response from endpoint #{uri}"
         | 
| 46 | 
            +
                    end
         | 
| 47 | 
            +
                  else
         | 
| 48 | 
            +
                    res.body
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def check_arguments(args, mandatory_args)
         | 
| 53 | 
            +
                  mandatory_args.each do |arg|
         | 
| 54 | 
            +
                    if (!args.has_key? arg)
         | 
| 55 | 
            +
                      raise(ArgumentError, "#{arg} not present")
         | 
| 56 | 
            +
                    end
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                def hmac_sha256(secret, data)
         | 
| 61 | 
            +
                  OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha256'), secret, data).unpack('H*').first
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                def concatenated(params)
         | 
| 65 | 
            +
                  params.collect { |k, v| k.to_s + '=' + v.to_s }.join('&')
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                def verify_signature(params, signature)
         | 
| 69 | 
            +
                  cert_data = Khipu::dev_env? ? Khipu::CERT_DEV : Khipu::CERT_PROD
         | 
| 70 | 
            +
                  cert = OpenSSL::X509::Certificate.new(cert_data)
         | 
| 71 | 
            +
                  pkey = cert.public_key
         | 
| 72 | 
            +
                  pkey.verify(OpenSSL::Digest::SHA1.new, Base64.decode64(signature), concatenated(params))
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              end
         | 
| 76 | 
            +
            end
         | 
    
        data/lib/khipu.rb
    ADDED
    
    | @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            require 'khipu/version'
         | 
| 2 | 
            +
            require 'khipu/khipu_service'
         | 
| 3 | 
            +
            require 'khipu/khipu_api_endpoint'
         | 
| 4 | 
            +
            require 'khipu/html_helper'
         | 
| 5 | 
            +
            require 'khipu/api_error'
         | 
| 6 | 
            +
            require 'khipu/const'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            module Khipu
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              API_URL = 'https://khipu.com/api/1.3/'
         | 
| 11 | 
            +
              DEBUG = ENV['KHIPU_DEBUG'] || false
         | 
| 12 | 
            +
              FORM_BUTTONS = {
         | 
| 13 | 
            +
                  '50x25'       => '50x25.png',
         | 
| 14 | 
            +
                  '100x25'      => '100x25.png',
         | 
| 15 | 
            +
                  '100x25white' => '100x25-w.png',
         | 
| 16 | 
            +
                  '100x50'      => '100x50.png',
         | 
| 17 | 
            +
                  '100x50white' => '100x50-w.png',
         | 
| 18 | 
            +
                  '150x25'      => '150x25.png',
         | 
| 19 | 
            +
                  '150x25white' => '150x25-w.png',
         | 
| 20 | 
            +
                  '150x50'      => '150x50.png',
         | 
| 21 | 
            +
                  '150x50white' => '150x50-w.png',
         | 
| 22 | 
            +
                  '150x75'      => '150x75.png',
         | 
| 23 | 
            +
                  '150x75white' => '150x75-w.png',
         | 
| 24 | 
            +
                  '200x50'      => '200x50.png',
         | 
| 25 | 
            +
                  '200x50white' => '200x50-w.png',
         | 
| 26 | 
            +
                  '200x75'      => '200x75.png',
         | 
| 27 | 
            +
                  '200x75white' => '200x75-w.png',
         | 
| 28 | 
            +
              }.inject({}) { |h, (k, v)| h[k] = 'htps://s3.amazonaws.com/static.khipu.com/buttons/' + v; h }
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              def self.create_khipu_api(receiver_id, secret = '')
         | 
| 31 | 
            +
                KhipuApiEndpoint.new(receiver_id, secret)
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              def self.create_html_helper(receiver_id, secret)
         | 
| 35 | 
            +
                HtmlHelper.new(receiver_id, secret)
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              def self.debug_stream
         | 
| 39 | 
            +
                $stdout
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              def self.dev_env?
         | 
| 43 | 
            +
                ENV['KHIPU_ENV'] == 'DEV'
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
            end
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe 'KhipuService' do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              it 'should calculate hmac' do
         | 
| 6 | 
            +
                service = Khipu::KhipuService.new(1234, '1234')
         | 
| 7 | 
            +
                hex_hmac = service.hmac_sha256('abcd', '1234')
         | 
| 8 | 
            +
                expect(hex_hmac).to eq('d219a3dd877f943be0ee65ef6a34129778d2fd0568ce2d9a8f37fea9d7fcaca3')
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              it 'should concatenate parameters' do
         | 
| 12 | 
            +
                service = Khipu::KhipuService.new(1234, '1234')
         | 
| 13 | 
            +
                params = service.concatenated(a: 1, b: 'foo', c: nil)
         | 
| 14 | 
            +
                expect(params).to eq('a=1&b=foo&c=')
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            require "khipu"
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,103 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: khipu
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 1.3.0
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Alex Lorca
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2014-04-29 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: bundler
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - ~>
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '1.3'
         | 
| 20 | 
            +
              type: :development
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - ~>
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '1.3'
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: rake
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - '>='
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: '0'
         | 
| 34 | 
            +
              type: :development
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - '>='
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: '0'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: rspec
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - '>='
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: '0'
         | 
| 48 | 
            +
              type: :development
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - '>='
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: '0'
         | 
| 55 | 
            +
            description: A wrapper for khipu's web API
         | 
| 56 | 
            +
            email:
         | 
| 57 | 
            +
            - alex.lorca@khipu.com
         | 
| 58 | 
            +
            executables: []
         | 
| 59 | 
            +
            extensions: []
         | 
| 60 | 
            +
            extra_rdoc_files: []
         | 
| 61 | 
            +
            files:
         | 
| 62 | 
            +
            - .gitignore
         | 
| 63 | 
            +
            - Gemfile
         | 
| 64 | 
            +
            - LICENSE.txt
         | 
| 65 | 
            +
            - README.md
         | 
| 66 | 
            +
            - Rakefile
         | 
| 67 | 
            +
            - khipu.gemspec
         | 
| 68 | 
            +
            - lib/khipu.rb
         | 
| 69 | 
            +
            - lib/khipu/api_error.rb
         | 
| 70 | 
            +
            - lib/khipu/const.rb
         | 
| 71 | 
            +
            - lib/khipu/html_helper.rb
         | 
| 72 | 
            +
            - lib/khipu/khipu_api_endpoint.rb
         | 
| 73 | 
            +
            - lib/khipu/khipu_service.rb
         | 
| 74 | 
            +
            - lib/khipu/version.rb
         | 
| 75 | 
            +
            - spec/khipu_service_spec.rb
         | 
| 76 | 
            +
            - spec/spec_helper.rb
         | 
| 77 | 
            +
            homepage: https://github.com/khipu/lib-ruby
         | 
| 78 | 
            +
            licenses:
         | 
| 79 | 
            +
            - BSD
         | 
| 80 | 
            +
            metadata: {}
         | 
| 81 | 
            +
            post_install_message: 
         | 
| 82 | 
            +
            rdoc_options: []
         | 
| 83 | 
            +
            require_paths:
         | 
| 84 | 
            +
            - lib
         | 
| 85 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 86 | 
            +
              requirements:
         | 
| 87 | 
            +
              - - '>='
         | 
| 88 | 
            +
                - !ruby/object:Gem::Version
         | 
| 89 | 
            +
                  version: '1.9'
         | 
| 90 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 91 | 
            +
              requirements:
         | 
| 92 | 
            +
              - - '>='
         | 
| 93 | 
            +
                - !ruby/object:Gem::Version
         | 
| 94 | 
            +
                  version: '0'
         | 
| 95 | 
            +
            requirements: []
         | 
| 96 | 
            +
            rubyforge_project: 
         | 
| 97 | 
            +
            rubygems_version: 2.0.7
         | 
| 98 | 
            +
            signing_key: 
         | 
| 99 | 
            +
            specification_version: 4
         | 
| 100 | 
            +
            summary: A wrapper for khipu's web API
         | 
| 101 | 
            +
            test_files:
         | 
| 102 | 
            +
            - spec/khipu_service_spec.rb
         | 
| 103 | 
            +
            - spec/spec_helper.rb
         |