I've been trying (fruitlessly!) to get PayPals SetPaymentOptions API feature to work, as per: https://developer.paypal.com/docs/classic/api/adaptive-payments/SetPaymentOptions_API_Operation/
FWIW - I'm aware the below isn't truly JSON, but its the Perl object I'm creating - which gets converted into JSON before sending (its just easier to read like this, compared to having it all on one line =))
So far I create the initial payment using the "Pay" feature (https://svcs.sandbox.paypal.com/AdaptivePayments/Pay):
{
requestEnvelope => {
detailLevel => "ReturnAll",
errorLanguage => "en_US",
},
actionType => "PAY",
currencyCode => "USD",
receiverList => {
receiver => [
{
amount => 65,
email => 'user1#gmail.com',
paymentType => "GOODS",
invoiceId => "test"
},
{
amount => 15,
email => 'user2#gmail.com',
paymentType => "GOODS",
invoiceId => "test 2"
}
],
},
returnUrl => 'http://xx.com/thanks.html',
cancelUrl => 'http://xx.com/cancel.html',
}
This creates it fine, and I get returned back the payKey just fine. The problem starts when I try and add shipping/units prices/taxes etc via SetPaymentOptions. Here is an example request I'm making:
{
payKey => $json_returned->{payKey},
requestEnvelope => {
detailLevel => "ReturnAll",
errorLanguage => "en_US",
},
receiverOptions => [
{
customId => "foo123",
receiver => {
email => 'andy-facilitator#ultranerds.com'
},
invoiceData => {
item => [{
name => "ITEM1",
price => 50,
itemCount => 2,
itemPrice => 25,
}],
totalTax => 5,
totalShipping => 10,
},
SenderOptions => {
addressOverride => 1,
requireShippingAddressSelection => 1
}
}
]
}
I then grab back that transaction to see if it all got saved ok, by using a PaymentDetails request (https://svcs.sandbox.paypal.com/AdaptivePayments/PaymentDetails)
This always comes back with no shipping, tax, unit numbers, etc. I'm at a real loss as to whats going on - because if I were to change (for example) the number of units in this 2nd request, or the delivery price... it gives me an error that the numbers don't match up! So it has to be recognizing it - but just not doing anything with it
I'm really at my witts end here (I wish they'd hurry up and get the REST APIs finished up - as they look more promising than this... but for now, I've got to make do with what we have here with the Adaptive Payments)
UPDATE:
Is this what you mean with regards to running the ExecutePayment?
my $pass_in_params = {
payKey => $json_returned->{payKey},
requestEnvelope => {
detailLevel => "ReturnAll",
errorLanguage => "en_US",
},
actionType => "CREATE"
};
WAHOO - Finally got it working! As per Andrews info, the reason I wasn't seeing the shipping/units/tax stuff with the ExecutePayment request, is because we hadn't sent them to the payment page yet (and you can't grab it until the payment is complete). With the Sandbox, you can login to a test account and see all the units etc perfectly.
When you use Pay with CREATE and then call SetPaymentOptions behind that, no payment occurs until you finish it up with ExecutePayment. As such, when you call PaymentDetails there are no details to obtain.
Try calling ExecutePayment to finish things off and then see if PaymentDetails works better for you.
Related
I am trying to test the Paypal Delayed Chained Payment API's.
There are two receivers 'A' and 'B', A is a primary receiver (US) and B is the second receiver (MX) when I release the payment using the Execute API the second receiver is not receiving the payment but the payments are being deducted from the buyer and primary accounts.
I am adding the request array below.
[
'actionType' => 'PAY_PRIMARY',
'clientDetails' => [
'applicationId' => 'APP-80W284485P519543T',
'ipAddress' => '127.0.0.1'
],
'currencyCode' => 'USD',
'feesPayer' => 'EACHRECEIVER',
'memo' => 'Example',
'receiverList' => [
'receiver' => [
[
'email' => 'A-Primary#appinventiv.com',
'primary' => true,
'amount' => 25,
],
[
'email' => 'B-Second#appinventiv.com',
'primary' => false,
'amount' => 20,
]
]
],
'requestEnvelope' => [
'errorLanguage' => 'en_US'
],
'returnUrl' => 'http://localhost/hairInferno/success.php',
'cancelUrl' => 'http://localhost/hairInferno/success.php'
];
Adaptive Payments was discontinued in December 2017 and no new APP IDs are generated for use in the live environment, so I'd drop this integration pattern
You could look around the PayPal for Partners documentation, but I'm not sure whether any of this would be available to you: https://developer.paypal.com/docs/partners/
Something with Payouts might be the best interim solution: https://developer.paypal.com/docs/payouts/
i have integrated paypal to my ecommerce using ruby on rails but it always redirected to the old paypal UI instead of the latest UI. here is the old UI i mentioned:
here is roughly my code. once create order submit button pressed, my order controller will redirect to the encrypted paypal link.
order_controller.rb
def create
redirect_to #order.paypal_url(root_url, shipping_fees, payment_notification_url)
in my order model, the encrypted link code as below:
order.rb
def paypal_url(return_url, shipping_fees, notify_url)
encrypted = {
:cmd => "_s-xclick",
:encrypted => self.encrypt_for_paypal(return_url, shipping_fees, notify_url),
}
"https://www.paypal.com/cgi-bin/webscr?" + encrypted.to_query
end
def encrypt_for_paypal(return_url, shipping_fees, notify_url)
#def paypal_url(return_url, shipping_fees, notify_url)
values = {
:business => 'cxxx#hotmail.com',
:cmd => '_cart',
:upload => 1,
:currency_code => 'MYR',
:return => return_url,
:invoice => self.number,
:notify_url => notify_url,
:cert_id => "XXX",
}
line_items.each_with_index do |item, index|
values.merge!({
"amount_#{index+1}" => item.final_price,
"item_name_#{index+1}" => Product.where(id: item.variant.product_id).pluck(:title),
"item_number_#{index+1}" => item.variant.SKU,
"quantity_#{index+1}" => item.quantity,
"shipping_1" => shipping_fees
})
end
encrypted_paypal(values)
end
PAYPAL_CERT_PEM = File.read("#{Rails.root}/certs/paypal_cert.pem")
APP_CERT_PEM = File.read("#{Rails.root}/certs/app_cert.pem")
APP_KEY_PEM = File.read("#{Rails.root}/certs/app_key.pem")
def encrypted_paypal(values)
signed = OpenSSL::PKCS7::sign(OpenSSL::X509::Certificate.new(APP_CERT_PEM), OpenSSL::PKey::RSA.new(APP_KEY_PEM, ''), values.map { |k, v| "#{k}=#{v}" }.join("\n"), [], OpenSSL::PKCS7::BINARY)
OpenSSL::PKCS7::encrypt([OpenSSL::X509::Certificate.new(PAYPAL_CERT_PEM)], signed.to_der, OpenSSL::Cipher::Cipher::new("DES3"), OpenSSL::PKCS7::BINARY).to_s.gsub("\n", "")
end
please advise because i read somewhere i need to insert :method => POST to the link but im not sure how. many thanks
I have created a paypal recurring payment with a trial period of 1 month. I am testing with my sandbox account.
After completing 1 payment I can see in my sandbox merchant account that the recurring payment has been created. But it's displaying: "recurring cycle remaining 1 month" and I have received $0. I mean the recurring payment has been started, but I am not receiving the money.
Is that paypal's fault or is there a problem with my code?
Well I am using a CMS(Social Eninge) . Paypal has been integrated here already . So I am just modifying it. Here is the parameters I am sending.
// This Portion to display the payment summery :
$params['driverSpecificParams']['PayPal'] = array(
'ITEMCATEGORY'=> 'Digital',
'AMT' => $params['price'],
'NAME' => $package->title,
'DESC' => $desc,
'ITEMS' => array(
array(
'NAME' => $package->title,
'AMT' => $params['price'],
'QTY' => 1,
),
),
'BILLINGTYPE' => 'RecurringPayments',
'BILLINGAGREEMENTDESCRIPTION' => $desc,
);
// And this portion for payment subscription.
$rpData = array(
'TOKEN' => $params['token'],
'PROFILEREFERENCE' => $order->order_id,
'PROFILESTARTDATE' => $data['TIMESTAMP'],
'DESC' => $desc, //Item Description
'BILLINGPERIOD' => ucfirst($package->recurrence_type),
'BILLINGFREQUENCY' => $package->recurrence,
'INITAMT' => 0 ,
'TRIALBILLINGPERIOD' => ucfirst($package->recurrence_type),
'TRIALBILLINGFREQUENCY' => $package->recurrence,
'TRIALTOTALBILLINGCYCLES' => 1,
'TRIALAMT' => $_SESSION["price"],
'AMT' => $package->price,
'CURRENCYCODE' => $this->getGateway()->getCurrency(),
);
I would also like to know whether setting $0 for a few months in my trial period will work or not ?
Paypal displaying like this :
[1]: https://i.stack.imgur.com/mSxk1.png
Well, I have found my code is right. It's paypal's delay for few hours.
Also setting $0 for trial period works perfectly. Trial period automatically choose the starting interval. You need to pass for how many days ,months, year, or week you wanna offer trial and which price, it might be lower price or zero doesn't matters.Like I am offering 1st month free/some reduced price after that it will continue the normal price.
I am creating Paypal buttons on the fly for shopping cart processing. I've used Express Checkout with no issues but the client does not want customers to have to complete the billing details on the EC page, using Hosted Payment buttons seems to be the solution.
I create the button using the NVP code sending the following:
(
[L_BUTTONVAR0] => business=emailaddress
[L_BUTTONVAR1] => paymentaction=sale
[L_BUTTONVAR2] => currency_code=AUD
[L_BUTTONVAR3] => cancel_return=http://localhost/orders/view/335774
[L_BUTTONVAR4] => notify_url=http://localhost/orders/complete_hostedpaypal/335774
[L_BUTTONVAR5] => return=http://localhost/orders/view/335774
[L_BUTTONVAR6] => invoice=Order #335774
[L_BUTTONVAR7] => subtotal=167.40
[L_BUTTONVAR8] => tax=2
[L_BUTTONVAR9] => shipping=3
[L_BUTTONVAR10] => handling=4
[L_BUTTONVAR11] => template=templateC
[L_BUTTONVAR12] => first_name=TEST
[L_BUTTONVAR13] => last_name=ORDER
[L_BUTTONVAR14] => buyer_email=emailaddress
[L_BUTTONVAR15] => address1=PO Box 2633
[L_BUTTONVAR16] => address2=
[L_BUTTONVAR17] => city=TAREN POINT
[L_BUTTONVAR18] => state=NSW
[L_BUTTONVAR19] => country=AU
[L_BUTTONVAR20] => zip=2229
[L_BUTTONVAR21] => billing_first_name=TEST
[L_BUTTONVAR22] => billing_last_name=ORDER
[L_BUTTONVAR23] => billing_address1=PO Box 2633
[L_BUTTONVAR24] => billing_address2=
[L_BUTTONVAR25] => billing_city=TAREN POINT
[L_BUTTONVAR26] => billing_state=NSW
[L_BUTTONVAR27] => billing_country=AU
[L_BUTTONVAR28] => billing_zip=2229
[L_BUTTONVAR29] => showBillingAddress=false
[L_BUTTONVAR30] => showShippingAddress=false
[L_BUTTONVAR31] => address_override=false
[L_BUTTONVAR32] => bn=AUD
[L_BUTTONVAR33] => lc=AU
[METHOD] => BMCreateButton
[BUTTONCODE] => TOKEN
[BUTTONTYPE] => PAYMENT
[USER] => [api_user]
[PWD] => [api_pwd]
[SIGNATURE] => [api_sig]
[VERSION] => 109.0
)
This returns ACK "Success" and the relevant code for the button and links...
When I navigate to the link the Paypal page https://securepayments.sandbox.paypal.com/webapps/HostedSoleSolutionApp/webflow/sparta/hostedSoleSolutionProcess?hosted_button_id=HSSS-BPdXvwvPaocw3NpZuxuIhGZuRL1DXlbqFgOo1BvzVYWKoSNjWyYwVilsDmt-QRxxvPmrlA shows:
Error Processing Payment
Error Message "This transaction can't be processed. Please pay with another card."
I emailed Paypal Merchant Services but have not had a response for some weeks now. Does anyone have any ideas?
I have upgraded the sandbox to pro.
I made a test using your parameters and generated a payment link, it worked for me(got redirected to templateC page and made a card payment). I used my own test pro account though. Are you seeing the error after you entered card info? If so you may create a fake credit card number on this page, step 4,
https://www.paypal-knowledge.com/infocenter/index?page=content&widgetview=true&id=FAQ1413&viewlocale=en_US&direct=en
How are you supposed to get the shipping info back from a Parallel Payment, using PayPal's Adaptive API system? Normally it would just get passed back as payer_country, etc - when the IPN script is requested. However, this doesn't seem to be the case.
Here are the params being passed in when the IPN script is called:
transaction[0].amount
transaction[0].id
verify_sign
transaction[1].receiver
reverse_all_parallel_payments_on_error
transaction[1].pending_reason
transaction[0].pending_reason
transaction[1].id_for_sender_txn
transaction[0].invoiceId
payment_request_date
test_ipn
cancel_url
charset
return_url
transaction[0].status_for_sender_txn
ipn_notification_url
transaction[1].is_primary_receiver
transaction[1].status
transaction_type
transaction[1].amount
transaction[0].status
log_default_shipping_address_in_transaction
transaction[0].receiver
status
transaction[0].id_for_sender_txn
action_type
fees_payer
pay_key
transaction[1].status_for_sender_txn
transaction[0].paymentType
transaction[1].invoiceId
transaction[1].id
sender_email
notify_version
transaction[1].paymentType
transaction[0].is_primary_receiver
If I then do a PaymentDetails API call, I get back stuff like:
$VAR1 = {
'currencyCode' => 'USD',
'responseEnvelope' => {
'correlationId' => '9944330ab9a8c',
'timestamp' => '2014-04-07T06:08:16.094-07:00',
'ack' => 'Success',
'build' => '10273932'
},
'status' => 'COMPLETED',
'senderEmail' => 'andy.aaaa#ultranerds.co.uk',
'cancelUrl' => 'http://somesite.net/paypal/cancel.html',
'paymentInfoList' => {
'paymentInfo' => [
{
'pendingRefund' => 'false',
'receiver' => {
'accountId' => 'NY3AD33DD739C',
'email' => 'andy-xxx#ultranerds.com',
'amount' => '65.00',
'invoiceId' => '1022',
'primary' => 'false',
'paymentType' => 'GOODS'
},
'transactionId' => '8E1114341X895213Y',
'senderTransactionStatus' => 'COMPLETED',
'senderTransactionId' => '5EV71352C33256006',
'transactionStatus' => 'COMPLETED',
'refundedAmount' => '0.00'
},
{
'pendingRefund' => 'false',
'receiver' => {
'accountId' => 'YYP5C69YWCMKE',
'email' => 'andy.yyy#gmail.com',
'amount' => '15.00',
'invoiceId' => '1023',
'primary' => 'false',
'paymentType' => 'GOODS'
},
'transactionId' => '68H86656UP574062X',
'senderTransactionStatus' => 'COMPLETED',
'senderTransactionId' => '2XW88939LK1112523',
'transactionStatus' => 'COMPLETED',
'refundedAmount' => '0.00'
}
]
},
'feesPayer' => 'EACHRECEIVER',
'actionType' => 'CREATE',
'ipnNotificationUrl' => 'http://somesite.net/paypal/test_ipn.cgi',
'sender' => {
'useCredentials' => 'false',
'accountId' => 'B74RBM5F6SLZG',
'email' => 'andy.aaa#ultranerds.co.uk'
},
'returnUrl' => 'http://somesite.net/paypal/success.html',
'payKey' => 'AP-4EK17906VB6613533',
'reverseAllParallelPaymentsOnError' => 'false'
};
As you can see, there is no reference to the delivery address at all. How are you supposed to get that info back?
UPDATE: Mmm ok, so it looks like GetShippingAddresses is what I need - but for some reason its coming back with nothing in when I call it:
{"requestEnvelope":{"errorLanguage":"en_US","detailLevel":"ReturnAll"},"key":"AP-1B1377463N9785350"} /GetShippingAddresses_API_Operation/
...simply returns:
{
'responseEnvelope' => {
'correlationId' => '3a4443aed09c9',
'timestamp' => '2014-04-07T06:40:35.460-07:00',
'ack' => 'Success',
'build' => '10273932'
}
}
I'm a bit baffled as to why its doing that. Any suggestions?
I found a quote here:
http://go.developer.ebay.com/devzone/articles/using-paypals-adaptive-payments-and-google-app-engine-build-online-market-python-part-3
Unfortunately, although this follows the process recommended by
PayPal's documentation, it doesn't work. There's currently a bug in
PayPal's Adaptive Payments implementation. For a traditional payment,
the shipping address is not collected; for embedded payments, the
GetShippingAddresses call does not return the shipping address.
PayPal has acknowledged the bug and indicated that it expects to have
this fixed in April 2011. If you need shipping addresses right now,
the recommendation is to collect them on your site rather than relying
on the PayPal API.
That was from 2011... but is this still the case??
Sorry to bump - but has anyone got any suggestions?
Ok, well I got my answer - but unfortunately its not what I was hoping for:
Yes, unfortunately this feature is only available for embedded payment
flow.
https://developer.paypal.com/webapps/developer/docs/classic/adaptive-payments/ht_ap-embeddedPayment-curl-etc/
If you're using embedded payment flow, then you can retrieve the
address on their PayPal account by passing in
senderOptions.requireShippingAddressSelection = true during
SetPaymentOption API call. You can then retrieve it via
GetShippingAddresses API call.
So it looks like really what I need to do, is ask the user to provide their shipping information BEFORE sending them to paypal, then storing it. Not ideal - but I guess you just have to work with what you got!