Reputation: 1101
I'm working on integrating a Rails app with the Paymill payment gateway (using the paymill-ruby gem), and was wondering if someone could give some advice to the best way to go about interacting with the API during a standard order process. I've managed to get the basics working, but there are very few resources on how to structure the full process.
I have a User model, where I want to store the paymill client id and payment id, and a Payment model, where I store details of every transaction (referencing the order id). My Payment model code is currently as follows:
class Payment < ActiveRecord::Base
include ActiveModel::ForbiddenAttributesProtection
attr_accessor :paymill_card_token, :email, :paymill_client_id, :paymill_payment_id
belongs_to :order
belongs_to :user
validates_presence_of :order_id
validates_presence_of :user_id
def save_with_payment
if valid?
if paymill_client_id.blank?
#if user hasn't paid before, create paymill client
client = Paymill::Client.create email: email, description: user_id
paymill_client_id = client.id
# update current user with paymill client ID
User.where("user_id = ?", user_id).update_attributes(:paymill_client_id => paymill_client_id)
end
if paymill_payment_id.blank?
#if paymill_payment_id isn't present, create new payment
payment = Paymill::Payment.create token: paymill_card_token, client: paymill_client_id
paymill_payment_id = payment.id
# update current user with paymill payment ID
User.where("user_id = ?", user_id).update_attributes(:paymill_payment_id => paymill_payment_id)
end
transaction = Paymill::Transaction.create client: paymill_client_id, amount: "#{amount.to_s.gsub('.', '')}0", currency: 'GBP', description: "ORDER ID #{order_id}", payment: paymill_payment_id
self.paymill_id = transaction.id
save!
end
rescue Paymill::PaymillError => e
logger.error "Paymill error while creating customer: #{e.message}"
errors.add :base, "There was a problem with your credit card. Please try again."
false
end
end
I read somewhere in the documentation that the paymill payment object (a client's saved credit card details) is only valid for one year - is this correct? And if so how should this be dealt with? Is it a good idea to store this expiry date, as well as the users credit card expiry date, in my User model so I know when to ask them to enter their card info again?
Upvotes: 4
Views: 639
Reputation: 116
valid paymentobject - yes you are right the paymentobject is only valid for 364 days, but it is extended for another 364 days starting from the last transaction again. Important! The token should only be used one time till you receive the paymentobject in the successfull response of the transaction or preauth. Afterwards please use the paymentobject. We will change this behaviour that the token only can be used one time in our API Version 3.
webhooks - right now there is no webhook for an expired paymentobject, but we will implement such a token which alerts you after a card will be expiring in the next days. But will take some months. Till than you should save the expiry date. There is no problem about PCI Security to save this information.
Best, Christian
Upvotes: 1
Reputation: 2125
Suggested changes:
Payment
model to store the payment_card_token
and payment_id
. This will allow you to support multiple cards per client, in case you need to in the futurePaymentTransaction
model and db table. Each time the user makes a payment, store the details in a PaymentTransaction
model instead of Payment
model.Also, a general observation about your rails code
User.where("user_id = ?", user_id).update_attributes
, just say user.update_attributes
as you have already define the association.if paymill_client_id
block of code to the User model.Upvotes: 1