Skip to content

Commit

Permalink
Fixes based on feedback from Klarna tech preparing for first public r…
Browse files Browse the repository at this point in the history
…elease.
  • Loading branch information
grimen committed Oct 16, 2011
1 parent 7d585a4 commit 5add30a
Show file tree
Hide file tree
Showing 13 changed files with 317 additions and 171 deletions.
10 changes: 9 additions & 1 deletion README.textile
Expand Up @@ -10,6 +10,14 @@ h2. What is Klarna?

Sweden (SE), Norway (NO), Denmark (DK), Finland (FI), Germany (DE), Netherlands (NL).

h2. Implementation/Background

This gem was developed as a semi-1:1 implementation of the corresponding API implementations provided by Klarna (with a few simple justifications and heavily refactored methods). Klarnas official implementations were not implemented using OO patterns and as their implementation was changing very often without any notice/versioning I kept it simple as possible.

Since Klarna 2.0 was released they'va refactored their implementations a lot which makes it a good idea to review this implementation as well. Like stated in the TODO I had a clean classy DSL in mind.

This is not a complete implementation, but not far from it and enough for most use cases - a few of the more advanced API methods needs a review/revisit (code disabled now).

h2. Setup

Install the gem:
Expand Down Expand Up @@ -123,7 +131,7 @@ This gem was developed for our own requirements at "Merchii":http://github.com/m

h2. To-do

This is not a complete implementation, but not far from it though. I had bigger plans way back when we wrote this, but since I assume Klarna will release a completely new API soon (_Klarna 2.0_ which I assume will be REST API?) - we're not sure we will bother to "finish" the planned features for the current XML-RPC API. Time will tell. For more details, see the "TODO":https://github.com/merchii/klarna-ruby/blob/master/TODO.
See the "TODO":https://github.com/merchii/klarna-ruby/blob/master/TODO.

h2. License

Expand Down
14 changes: 8 additions & 6 deletions TODO
@@ -1,15 +1,16 @@

== CURRENT

x [feature]: Implement the last missing Invoicing methods
-----
* [feature]: Review/Implement something like: our_settype_integer, our_strip_string, our_settype_string (consider one generic method, e.g. parse(:price, value) - all validation/masking/casting in one place)
* [feature]: Ensure valid string format/stripping (e.g. SSN, etc)
* [feature]: Ensure correct params datatypes are submitted (validation - consider generic method)
x [issue]: Test the invoice activation in a proper way - not allowed in the Klarna 2.0 API (for some weird reason...)


== HIGH-PRIO

* [feature]: Review/Implement something like: our_settype_integer, our_strip_string, our_settype_string (consider one generic method, e.g. parse(:price, value) - all validation/masking/casting in one place)
* [feature]: Ensure valid string format/stripping (e.g. SSN, etc) using regular expressions
* [feature]: Compare implementation with Klarna's new API 2.0
* [feature]: Ensure correct params datatypes are submitted (validation - consider generic method)
* [feature]: Klarna::DSL - wrapper DSL for less sucky integrations
* [feature]: Implement #get_pclasses method to export pclasses as hash (and maybe export to YAML?)
* [feature]: ActiveMerchant-integration (fork ActiveMerchant and add klarna as new gateway with "klarna-ruby" as dependency)

Expand All @@ -18,11 +19,12 @@ x [feature]: Implement the last missing Invoicing methods

* [feature]: Finalize the rest of the specs for already implemented methods, commented out currently.
* [feature]: Implement Reservation methods
* [feature]: Klarna::DSL - wrapper DSL for less sucky integrations
* [feature]: Bring back "examples/web" - probably not working at all now.
* [feature]: Rack middleware?


== MAYBE

* [feature]: Mock XML-responses by default to avoid live API calls, but allow live calls using ENV['REMOTE]=true

https://github.com/myronmarston/vcr
8 changes: 4 additions & 4 deletions lib/klarna/api/client.rb
Expand Up @@ -9,7 +9,7 @@ class Client < ::XMLRPC::Client

include ::Klarna::API::Methods

attr_accessor :store_id,
attr_accessor :store_id,
:store_secret,
:mode,
:timeout,
Expand Down Expand Up @@ -79,15 +79,15 @@ def ssl?
alias :use_ssl? :ssl?

def protocol
@protocol ||= ::Klarna::API::END_POINT[self.mode][:protocol]
@protocol = ::Klarna::API::END_POINT[self.mode][:protocol]
end

def host
@host ||= ::Klarna::API::END_POINT[self.mode][:host]
@host = ::Klarna::API::END_POINT[self.mode][:host]
end

def port
@port ||= ::Klarna::API::END_POINT[self.mode][:port]
@port = ::Klarna::API::END_POINT[self.mode][:port]
end

def endpoint_uri
Expand Down
8 changes: 4 additions & 4 deletions lib/klarna/api/constants.rb
Expand Up @@ -10,17 +10,17 @@ module Constants
END_POINT = {
:test => {
:protocol => 'http',
:host => 'payment.klarna.com',
:host => 'payment-beta.klarna.com',
:port => 80
},
:production => {
:protocol => 'http',
:protocol => 'https',
:host => 'payment.klarna.com',
:port => 80
:port => 443
}
}.freeze

PROTOCOL_ENCODING = 'iso-8859-1'.freeze # ['UTF-8', 'ISO-8859-1', 'US-ASCII'].freeze
PROTOCOL_ENCODING = 'iso-8859-1'.freeze # NOTE: New API supports: ['UTF-8', 'ISO-8859-1', 'US-ASCII'].freeze
PROTOCOL_VERSION = '4.0'.freeze

# -----------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion lib/klarna/api/methods/cost_calculations.rb
Expand Up @@ -5,7 +5,7 @@ module API
module Methods
module CostCalculations

# Purpose: Obtain pcalss values from Klarna.
# Purpose: Obtain pclass values from Klarna.
#
# == Note:
#
Expand Down
72 changes: 41 additions & 31 deletions lib/klarna/api/methods/invoicing.rb
Expand Up @@ -12,7 +12,7 @@ module Invoicing

# Create an invoice.
#
def add_invoice(store_user_id, order_id, goods_list, shipping_fee,
def add_invoice(store_user_id, order_id, articles, shipping_fee,
handling_fee, shipment_type, pno, first_name, last_name, address, client_ip,
currency, country, language, pno_encoding, pclass = nil, annual_salary = nil,
password = nil, ready_date = nil, comment = nil, rand_string = nil, new_password = nil, flags = nil)
Expand All @@ -23,13 +23,14 @@ def add_invoice(store_user_id, order_id, goods_list, shipping_fee,
pno_encoding = ::Klarna::API.id_for(:pno_format, pno_encoding)
pclass = pclass ? ::Klarna::API.id_for(:pclass, pclass) : -1
flags = ::Klarna::API.parse_flags(:INVOICE, flags)
articles = Array.wrap(articles).compact

params = [
self.store_id,
store_user_id,
self.digest(goods_list.collect { |g| g[:goods][:title] }, :store_id => false),
self.digest(articles.collect { |g| g[:goods][:title] }, :store_id => false),
order_id,
goods_list,
articles,
shipping_fee,
shipment_type,
handling_fee,
Expand Down Expand Up @@ -70,6 +71,7 @@ def add_invoice(store_user_id, order_id, goods_list, shipping_fee,
def activate_invoice(invoice_no, articles = nil)
# TODO: Parse/Validate invoice_no as :integer
# TODO: Parse/Valdiate articles as array of articles
articles = Array.wrap(articles).compact

params = [
self.store_id,
Expand All @@ -79,7 +81,7 @@ def activate_invoice(invoice_no, articles = nil)
# Only partly?
if articles.present?
params << articles
params << self.digest(invoice_no, articles.collect { |a| a.join(':') }.join(':'))
params << self.digest(invoice_no, articles.collect { |a| [a[:goods][:artno], a[:qty]].join(':') }.join(':'))
method = :activate_part
else
params << self.digest(invoice_no)
Expand Down Expand Up @@ -107,36 +109,37 @@ def delete_invoice(invoice_no)
# Give discounts for invoices.
#
def return_amount(invoice_no, amount, vat)
# params = [
# self.store_id,
# invoice_no,
# amount,
# vat,
# self.digest(invoice_no)
# ]
# self.call(:return_amount, *params)
raise NotImplementedError
params = [
self.store_id,
invoice_no,
amount,
vat,
self.digest(invoice_no)
]
self.call(:return_amount, *params) # raise NotImplementedError
end

# Return a invoice - optionally only partly.
#
def credit_invoice(invoice_no, credit_id, articles = nil)
# params = [
# self.store_id,
# invoice_no,
# credit_id,
# ]
# # Only partly?
# if articles.present?
# params << articles
# params << self.digest(invoice_no, articles.collect { |a| a.join(':') }.join(':'))
# method = :credit_part
# else
# params << self.digest(invoice_no)
# method = :credit_invoice
# end
# self.call(method, *params)
raise NotImplementedError
articles = Array.wrap(articles).compact

params = [
self.store_id,
invoice_no,
credit_id,
]

if articles.present? # Only partly?
params << articles
params << self.digest(invoice_no, articles.collect { |a| [a[:goods][:artno], a[:qty]].join(':') }.join(':'))
method = :credit_part
else
params << self.digest(invoice_no)
method = :credit_invoice
end

self.call(method, *params)
end

# Send an active invoice to the customer via e-mail.
Expand Down Expand Up @@ -253,6 +256,13 @@ def invoice_address(invoice_no)
#
def invoice_amount(invoice_no, articles = nil)
# TODO: Parse/Validate invoice_no as integer
articles = Array.wrap(articles).compact
artnos =
if articles.first.respond_to?(:key?) && articles.first.key?(:qty) && articles.first.key?(:artno)
articles
else
articles.collect { |a| {:artno => a[:goods][:artno], :qty => a[:qty]} }
end

params = [
self.store_id,
Expand All @@ -261,8 +271,8 @@ def invoice_amount(invoice_no, articles = nil)

# Only partly?
if articles.present?
params << articles
params << self.digest(invoice_no, articles.collect { |a| a.join(':') }.join(':'))
params << artnos
params << self.digest(invoice_no, artnos.collect { |an| [an[:artno], an[:qty]].join(':') }.join(':'))
method = :invoice_part_amount
else
params << self.digest(invoice_no)
Expand Down
13 changes: 6 additions & 7 deletions lib/klarna/api/methods/standard.rb
Expand Up @@ -109,13 +109,12 @@ def make_goods(quantity, article_no, title, price, vat, discount = nil, flags =
# Check if a user has an account.
#
def has_account?(pno, pno_encoding)
# params = [
# self.store_id,
# self.digest(pno),
# pno_encoding
# ]
# self.call(:has_account, *params)
raise NotImplementedError
params = [
self.store_id,
self.digest(pno),
pno_encoding
]
self.call(:has_account, *params)
end

end
Expand Down
2 changes: 1 addition & 1 deletion lib/klarna/version.rb
@@ -1,5 +1,5 @@
# encoding: utf-8

module Klarna
VERSION = '0.1.2'
VERSION = '0.1.3'
end
2 changes: 1 addition & 1 deletion test/klarna/api/methods/cost_calculations_test.rb
Expand Up @@ -3,7 +3,7 @@

describe Klarna::API::Methods::CostCalculations do

# TODO: Mock responses.
# TODO: Mock responses using VCR.

before do
valid_credentials!
Expand Down

0 comments on commit 5add30a

Please sign in to comment.