Question

I´m integrating Paypal in my Rails web app. I need to implemement next use case:

  1. Customer buys a service and pay to my app.
  2. After some days, in example, a week, I pay the service provider, after keeping a fee. This point 2, I have an engine, that automatically checks if the date to pay the customer has come. If so, it tries to automatically pay the provider.

I have my point 1, implemented and working with Express Checkout. For my point 2, I understood I should use Adaptative payment API. But, it´s not working as I understood, so I´m not sure.

My first question is, I would like everything is automated, so, I don´t want any window to popup to confirm anything? is it possible to execute the operation automatically?

My code:

def pay(amount, paypalAccountEmail)

  # ## Build request object
  @pay_request = @api.build_pay()

  # The action for this request. Possible values are:
  # 
  # * PAY - Use this option if you are not using the Pay request in
  # combination with ExecutePayment.
  # * CREATE - Use this option to set up the payment instructions with
  # SetPaymentOptions and then execute the payment at a later time with
  # the ExecutePayment.
  # * PAY_PRIMARY - For chained payments only, specify this value to delay
  # payments to the secondary receivers; only the payment to the primary
  # receiver is processed.
  @pay_request.actionType         = "PAY"

  # URL to redirect the sender's browser to after
  # canceling the approval for a payment; it is always required but only
  # used for payments that require approval (explicit payments)
  @pay_request.cancelUrl          = "https://paypal-sdk-samples.herokuapp.com/adaptive_payments/pay"

  # The code for the currency in which the payment is
  # made; you can specify only one currency, regardless of the number of
  # receivers
  @pay_request.currencyCode       = "EUR"

  # The payer of PayPal fees. Allowable values are:
  # 
  # * SENDER - Sender pays all fees (for personal, implicit simple/parallel payments; do not use for chained or unilateral payments)
  # * PRIMARYRECEIVER - Primary receiver pays all fees (chained payments only)
  # * EACHRECEIVER - Each receiver pays their own fee (default, personal and unilateral payments)
  # * SECONDARYONLY - Secondary receivers pay all fees (use only for chained payments with one secondary receiver)
  @pay_request.feesPayer          = "SENDER"

  # The URL to which you want all IPN messages for this payment to be sent.
  @pay_request.ipnNotificationUrl = "https://paypal-sdk-samples.herokuapp.com/adaptive_payments/ipn_notify"

  # Amount to be paid to the receiver.
  @pay_request.receiverList.receiver[0].amount = amount

  # Receiver's email address. This address can be unregistered with paypal.com. If so, a receiver cannot claim the payment until a PayPal account is linked to the email address. The PayRequest must pass either an email address or a phone number.
  @pay_request.receiverList.receiver[0].email  = paypalAccountEmail

  # The URL to which the sender's browser is redirected after approving a payment on paypal.com. Specify the URL with the HTTP or HTTPS designator.
  @pay_request.returnUrl          = "https://paypal-sdk-samples.herokuapp.com/adaptive_payments/pay"

  # ## Make API call & get response
  @pay_response = @api.pay(@pay_request)

  # ## Access Response
  # ### Success Response

  if @pay_response.responseEnvelope.ack == "Success"
    # Once you get success response, user has to redirect to PayPal
    # for the payment. Construct redirectURL as follows,
    # `redirectURL=https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_ap-payment&paykey="
    # + @pay_response.payKey;`

    # The pay key, which is a token you use in other Adaptive
    # Payment APIs (such as the Refund Method) to identify this
    # payment. The pay key is valid for 3 hours; the payment must
    # be approved while the pay key is valid.
    puts  @pay_response.payKey

    # The status of the payment. Possible values are:
    # 
    # * CREATED - The payment request was received; funds will be transferred once the payment is approved
    # * COMPLETED - The payment was successful
    # * INCOMPLETE - Some transfers succeeded and some failed for a parallel payment or, for a delayed chained payment, secondary receivers have not been paid
    # * ERROR - The payment failed and all attempted transfers failed or all completed transfers were successfully reversed
    # * REVERSALERROR - One or more transfers failed when attempting to reverse a payment
    # * PROCESSING - The payment is in progress
    # * PENDING - The payment is awaiting processing
    puts "Pay Key : " + @pay_response.paymentExecStatus

    # ###Error Response
  else
    puts @pay_response.error[0].message

  end
  @pay_response
end

and my log:

providerPayment-->begin
Request[post]: https://svcs.sandbox.paypal.com/AdaptivePayments/Pay
Response[200]: OK, Duration: 1.417s
AP-1E607027P7722991V
Pay Key : CREATED
providerPayment-->ok

I took an example from Paypal but when I execute it, I see the result is ok. My actionType = "PAY". So, I want to pay, but in the key, I get = CREATED and nothing happens after that. I don´t want to create but to complete the transaction. What am I missing?

Was it helpful?

Solution

I don't see that you're redirecting the user anywhere..?? After you make the call to Pay you have to redirect the user over to PayPal to sign in and authenticate the payment. The only time you wouldn't do that is if you're including a preapproval key in the Pay request, but I don't see that you are.

You need append the paykey that you get to the end of the PayPal URL that you redirect to. Here's a sample: https://www.sandbox.paypal.com/webscr?cmd=_ap-payment&paykey=AP-3VV02679XF235284R

Until the user logs in and completes the payment for that paykey it will indeed just be created.

I actually do see some info about the redirect URL in the comments of your code, but I don't see anything actually doing that redirect to send the user there.

----- UPDATE -----

Now that I see you're doing an implicit payment, you just need to make sure to include the senderEmail in the request. Here's a sample of a Pay request I just made that worked with implicit approval so the redirect and further authentication was not necessary.

<?xml version="1.0" encoding="utf-8"?>
<PayRequest xmlns="http://svcs.paypal.com/types/ap">
  <requestEnvelope xmlns="">
    <detailLevel>ReturnAll</detailLevel>
    <errorLanguage>en_US</errorLanguage>
  </requestEnvelope>
  <actionType xmlns="">PAY</actionType>
  <cancelUrl xmlns="">http://paypal.angelleye.com/paypal/class/1.2/Pay_Cancel.php</cancelUrl>
  <clientDetails xmlns="">
    <applicationId xmlns="">APP-80W284485P519543T</applicationId>
    <ipAddress xmlns="">192.168.1.115</ipAddress>
    <partnerName xmlns="">Always Give Back</partnerName>
  </clientDetails>
  <currencyCode xmlns="">USD</currencyCode>
  <receiverList xmlns="">
    <receiver xmlns="">
      <amount xmlns="">10.00</amount>
      <email xmlns="">sandbo_1204199080_biz@angelleye.com</email>
    </receiver>
    <receiver xmlns="">
      <amount xmlns="">5.00</amount>
      <email xmlns="">usb_1329725429_biz@angelleye.com</email>
    </receiver>
  </receiverList>
  <sender>
    <useCredentials xmlns=""></useCredentials>
  </sender>
  <account xmlns="">
    <phone xmlns=""></phone>
  </account>
  <returnUrl xmlns="">http://paypal.angelleye.com/paypal/class/1.2/Pay_Return.php</returnUrl>
  <senderEmail xmlns="">sandbo_1215254764_biz@angelleye.com</senderEmail>
</PayRequest>

Here is the response, which shows the paymentExecStatus is fully completed as oppose to just created/pending like it would be without the implicit approval.

<?xml version='1.0' encoding='UTF-8'?>
<ns2:PayResponse xmlns:ns2="http://svcs.paypal.com/types/ap">
  <responseEnvelope>
    <timestamp>2014-01-20T07:53:08.420-08:00</timestamp>
    <ack>Success</ack>
    <correlationId>c74cd2a669678</correlationId>
    <build>7935900</build>
  </responseEnvelope>
  <payKey>AP-39D64611TH198910V</payKey>
  <paymentExecStatus>COMPLETED</paymentExecStatus>
  <paymentInfoList>
    <paymentInfo>
      <transactionId>0M064165EV3552504</transactionId>
      <transactionStatus>COMPLETED</transactionStatus>
      <receiver>
        <amount>10.00</amount>
        <email>sandbo_1204199080_biz@angelleye.com</email>
        <primary>false</primary>
        <accountId>E7BTGVXBFSUAU</accountId>
      </receiver>
      <pendingRefund>false</pendingRefund>
      <senderTransactionId>43F26555RA073153C</senderTransactionId>
      <senderTransactionStatus>COMPLETED</senderTransactionStatus>
    </paymentInfo>
    <paymentInfo>
      <transactionId>7K9309808X980452U</transactionId>
      <transactionStatus>COMPLETED</transactionStatus>
      <receiver>
        <amount>5.00</amount>
        <email>usb_1329725429_biz@angelleye.com</email>
        <primary>false</primary>
        <accountId>C9TAVNJFATXCS</accountId>
      </receiver>
      <pendingRefund>false</pendingRefund>
      <senderTransactionId>0M822840XM282203C</senderTransactionId>
      <senderTransactionStatus>COMPLETED</senderTransactionStatus>
    </paymentInfo>
  </paymentInfoList>
  <sender>
    <accountId>ATSCG2QMC9KAU</accountId>
  </sender>
</ns2:PayResponse>

So, whatever class library you're using should give you the ability to easily add the additional senderEmail parameter and that would solve your issue.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top