paymill-rails icon indicating copy to clipboard operation
paymill-rails copied to clipboard

Handling failed transactions.

Open andreaslyngstad opened this issue 10 years ago • 3 comments

This application is not handling the case where the transaction fails.

The Paymill Bridge will accept the credit card, but the transaction itself will get rejected.

So the tokenization will be successful as the credit card number format (the checksum, first digit ..) is correct but when you try to create a transaction you will receive an error.

You can for instance make a payment with the test cards like 4111 1111 1111 1111. It will go through the tokenization process, but when the transaction is made, Paymill will return something like this.

{
"data" : {
"id" : "tran_1f42e10cf14301067332",
"amount" : "4200",
"origin_amount" : 4200,
"status" : "closed",
"description" : null,
"livemode" : false,
"refunds" : null,
"currency" : "EUR",
"created_at" : 1349946151,
"updated_at" : 1349946151,
"response_code" : 40104, // Here you can find the response code
"short_id" : "0000.1212.3434",
"is_fraud" : false,
"invoices" : [],
"payment" : "<Object>",
"client" : "<Object>",
"preauthorization" : null,
"fees" : [],
"app_id" : null
},
"mode" : "test"
}

Your app have to handle this.

In your save_with_payment method, you only check if for api errors not transaction errors.

you could do something like this

  def save_with_payment
    if valid?
      client = Paymill::Client.create email: email, description: name
      payment = Paymill::Payment.create token: paymill_card_token, client: client.id
      subscription = Paymill::Subscription.create offer: plan.paymill_id, client: client.id, payment: payment.id
      if check_transaction?(client)
       self.paymill_id = subscription.id
       save!
      end
    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
 def check_transaction?(client)
    case Paymill::Transaction.all({client: client.id, order: "created_at_desc"})[0].response_code
      when 20000 then; return true
      # all the possible errors should be listed with translations. For instance
      when 40104 then errors.add :base, "Card invalid."; return false
      #40104 is the response_code you get when using a test card
      else errors.add :base, "Something whent wrong."; return false
    end
  end

andreaslyngstad avatar Nov 21 '14 09:11 andreaslyngstad

Thanks Andreas,

I'm not using paymill any more, but feel free to open a Pull Request and I'll merge it.

marcboquet avatar Nov 21 '14 09:11 marcboquet

I am sorry. I really do not have the time for it. Maybe you could add a link to this issue on the info page. New users should be warned about this issue.

andreaslyngstad avatar Nov 21 '14 09:11 andreaslyngstad

OK, I'll do that and leave this issue open, if someone wants to send a PR that would be great.

marcboquet avatar Nov 21 '14 10:11 marcboquet