Mangopay / mangopay2-ruby-sdk

Ruby Gem for MANGOPAY
https://rubygems.org/gems/mangopay
MIT License
42 stars 38 forks source link

PayIn error status PSP technical error with 3d secure test card #65

Closed dborovsky closed 7 years ago

dborovsky commented 8 years ago

We get this error when trying to create payment Direct PayIn with card 3d secure. We are implementing the same scenario as in this example https://github.com/Mangopay/mangopay2-php-sdk/blob/master/demos/paymentDirect/payment.php#L20 So initially we have a form that a user fills with his data like card id, ccv and that stuff. Then we use JavaScript SDK to submit this data to the MangoPay server. We also have an ajaxURL set that points to the URL on our server.

# create pay-in CARD DIRECT
      payIn = MangoPay::PayIn::Card::Direct.create(CreditedWalletId: current_user.wallet_id,
                                                   CardId: card['Id'],
                                                   AuthorId: card_registration['UserId'],
                                                   Tag: 'deposit',
                                                   SecureModeReturnURL: contract_url(@contract),
                                                   DebitedFunds: { Amount: (@contract.amount*100).to_i, Currency: 'EUR' },
                                                   Fees: { Amount: 0, Currency: 'EUR' },
                                                   # payment type as CARD
                                                   PaymentDetails: { CardType: card['CardType'], CardId: card['Id'] },
                                                   SecureMode: "DEFAULT")

return answer:

{"Id"=>"17198559",
 "Tag"=>"deposit",
 "CreationDate"=>1477642519,
 "AuthorId"=>"15460637",
 "CreditedUserId"=>"15460637",
 "DebitedFunds"=>{"Currency"=>"EUR", "Amount"=>30000},
 "CreditedFunds"=>{"Currency"=>"EUR", "Amount"=>30000},
 "Fees"=>{"Currency"=>"EUR", "Amount"=>0},
 "Status"=>"FAILED",
 "ResultCode"=>"009199",
 "ResultMessage"=>"PSP technical error",
 "ExecutionDate"=>nil,
 "Type"=>"PAYIN",
 "Nature"=>"REGULAR",
 "CreditedWalletId"=>"15460638",
 "DebitedWalletId"=>nil,
 "PaymentType"=>"CARD",
 "ExecutionType"=>"DIRECT",
 "SecureMode"=>"DEFAULT",
 "CardId"=>"17198553",
 "SecureModeReturnURL"=>nil,
 "SecureModeRedirectURL"=>nil,
 "SecureModeNeeded"=>true,
 "StatementDescriptor"=>nil}

registration_card.coffee

mangoPay.cardRegistration.sendDataWithAjax(
      # URL to capture response
      finialize_url,
      # Card data
      cardData,
      # Result Ajax callback
      (data) ->
        $this.replaceWith('<p>Votre paiement a bien été reçu.</p> </br> <div id="contract_url"><a href="">Voir le contrat</a></div>')
        $("#contract_url a").attr("href", contract_url)

        #doRedirect = -> window.location.href = data['url']
        #setTimeout doRedirect, 2000

      (xhr, status, error) ->
        location.reload()
        # $('body').prepend("<div class='alert alert-warning'>Payment error </div>");

use your test card: 3012349999999999

hobailey commented 8 years ago

Hey, just to check, what is the CardType of the card please? I'm seeing it on our side as "CB_VISA_MASTERCARD" even though the card number you're using is a Maestro :-/

dborovsky commented 8 years ago

hey, yes. sorry. now use 3569990000000132, but dont redirect to your page, where need input password.

return payIn

{"Id"=>"17200979",
 "Tag"=>"deposit",
 "CreationDate"=>1477646943,
 "AuthorId"=>"15460637",
 "CreditedUserId"=>"15460637",
 "DebitedFunds"=>{"Currency"=>"EUR", "Amount"=>30000},
 "CreditedFunds"=>{"Currency"=>"EUR", "Amount"=>30000},
 "Fees"=>{"Currency"=>"EUR", "Amount"=>0},
 "Status"=>"CREATED",
 "ResultCode"=>nil,
 "ResultMessage"=>nil,
 "ExecutionDate"=>nil,
 "Type"=>"PAYIN",
 "Nature"=>"REGULAR",
 "CreditedWalletId"=>"15460638",
 "DebitedWalletId"=>nil,
 "PaymentType"=>"CARD",
 "ExecutionType"=>"DIRECT",
 "SecureMode"=>"FORCE",
 "CardId"=>"17200978",
 "SecureModeReturnURL"=>"http://localhost:3000/contracts/09954cf4?transactionId=17200979",
 "SecureModeRedirectURL"=>"https://api.sandbox.mangopay.com:443/Redirect/ACSWithValidation?token=06f4a9611cd248cc87a59bfd72548080",
 "SecureModeNeeded"=>true,
 "StatementDescriptor"=>nil}

card_registration.coffee


jQuery ->
  $('#payment-form').submit (e) ->
    e.preventDefault()
    $this = $(this)

    # for disable submit button when do payment
    $('#process').attr("disabled", true)
    $('#process_name').replaceWith('<i class="fa fa-spinner fa-spin"></i> Paiement...')

    #convert date format to "mmyy"
    d = $("#card_expiration_date").val()
    if d.includes('20')
      d = d.replace('20', '')
    newDate = d.substr(0,2) + d.substr(5,2)
    newNumber = $("#card_number").val()
    newNumber = newNumber.replace(/ /g,'')
    mangoPay.cardRegistration.init
      cardRegistrationURL: $("#CardRegistrationURL").val()
      preregistrationData: $("#PreregistrationData").val()
      accessKey: $("#AccessKey").val()

    cardData = {
      cardNumber: newNumber
      cardExpirationDate: newDate
      cardCvx: $("#cardCvx").val()
    }
    contract_url =  $("#contractUrlHidden").val()
    finialize_url = $("#finializeUrl").val()
    mangoPay.cardRegistration.sendDataWithAjax(
      # URL to capture response
      finialize_url,
      # Card data
      cardData,
      # Result Ajax callback
      (data) ->
        $this.replaceWith('<p>Votre paiement a bien été reçu.</p> </br> <div id="contract_url"><a href="">Voir le contrat</a></div>')
        $("#contract_url a").attr("href", contract_url)

        #doRedirect = -> window.location.href = data['url']
        #setTimeout doRedirect, 2000

      (xhr, status, error) ->
        location.reload()
        # $('body').prepend("<div class='alert alert-warning'>Payment error </div>");

    )
    #console.log values_for_url
#     $.ajax(
#       type: "POST"
#       url: $("#CardRegistrationURL").val() #sumbits it to the given url of the form
#       data: values_for_url
#       dataType: "JSON" #you want a difference between normal and ajax-calls, and json is standard
#     ).success( (json) ->
# #      $.ajax(
# #        type: "POST"
# #        url: "/payments"
# #        beforeSend: $.rails.CSRFProtection
# #      )
#       #beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))}
#       beforeSend: $.rails.CSRFProtection
#       console.log(json)
#     )
    return false
hobailey commented 8 years ago

OK, so that looks better - but what is the problem now please?

dborovsky commented 8 years ago

problem is when create payment(MangoPay::PayIn::Card::Direct.create) dont redirect to page secure 3d.

return error not aceptable(eror 406) method:

mangoPay.cardRegistration.sendDataWithAjax(
      # URL to capture response
      finialize_url,
      # Card data
      cardData,
      # Result Ajax callback
      (data) ->
        $this.replaceWith('<p>Votre paiement a bien été reçu.</p> </br> <div id="contract_url"><a href="">Voir le contrat</a></div>')
        $("#contract_url a").attr("href", contract_url)

        #doRedirect = -> window.location.href = data['url']
        #setTimeout doRedirect, 2000

      (xhr, status, error) ->
        location.reload()
hobailey commented 8 years ago

Are you sure you're not mixing up the payin 3DS completion URL and the 3rd step of the card registration (where you do a PUT to Mangopay)? I don't understand why the payin is anything to do with mangoPay.cardRegistration.sendDataWithAjax

You should perhaps consider using our JS kit by the way?

dborovsky commented 8 years ago

1 step

Register card for user

@card_preregistration = MangoPay::CardRegistration.create(UserId: current_user.mangopay_id,
                                                              Currency: 'EUR',
                                                              CardType: 'CB_VISA_MASTERCARD')

2 step get RegistrationData from mangopay and update card. card_registration = MangoPay::CardRegistration.update(session[:card_id], RegistrationData: "data=#{params['data']}", Tag: 'custom tag')

3 step

payIn = MangoPay::PayIn::Card::Direct.create(CreditedWalletId: current_user.wallet_id,
                                                   CardId: card['Id'],
                                                   AuthorId: card_registration['UserId'],
                                                   Tag: 'deposit',
                                                   SecureModeReturnURL: contract_url(@contract),
                                                   DebitedFunds: { Amount: (@contract.amount*100).to_i, Currency: 'EUR' },
                                                   Fees: { Amount: 0, Currency: 'EUR' },
                                                   # payment type as CARD
                                                   PaymentDetails: { CardType: card['CardType'], CardId: card['Id'] },
                                                   # execution type as DIRECT
                                                   #ReturnURL: contract_url(@contract),
                                                   SecureMode: "FORCE")

Can you please tell is all correct or wich steps missed in direct payin?

hobailey commented 8 years ago

This seems perfect. And then if SecureModeNeeded==true in the response from the 3rd step, then you should redirect them to the SecureModeRedirectURL. But the 3rd step is something done on your server, so I'm not sure why there is confusion with Javascript calls (as per your previous comment).