I am using the Paypal API and I want to create a recurring payment, the first amount should be charged immediately. I need to know if it was successfully to unlock the content for the user. How in the world can I achieve that?
$fields = array(
'USER' => urlencode('email'),
'PWD' => urlencode('pass'),
'SIGNATURE' => urlencode('signature'),
'METHOD' => urlencode('GetExpressCheckoutDetails'),
'VERSION' => urlencode('86'),
'TOKEN' => urlencode($_GET['token'])
);
//url-ify the data for the POST
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string, '&');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://api-3t.sandbox.paypal.com/nvp");
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS,$fields_string); //Post Fields
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec ($ch);
curl_close ($ch);
// Get PAYERID of 1. query
$payerid = parseNVP($server_output);
$payerid = $payerid['PAYERID'];
$fields2 = array(
'USER' => urlencode('Email'),
'PWD' => urlencode('Pass'),
'SIGNATURE' => urlencode('Signature'),
'METHOD' => urlencode('CreateRecurringPaymentsProfile'),
'VERSION' => urlencode('86'),
'TOKEN' => urlencode($_GET['token']),
'PAYERID' => urlencode($payerid),
'PROFILESTARTDATE' => urlencode(date('Y-m-d').'T'.date('H:i:s', strtotime('-5 minutes')).'Z'),
'DESC' => urlencode('FitnessMembership'),
'BILLINGPERIOD' => urlencode('Day'),
'BILLINGFREQUENCY' => urlencode('1'),
'AMT' => urlencode($price),
'CURRENCYCODE' => urlencode('USD'),
'COUNTRYCODE' => urlencode('US'),
'MAXFAILEDPAYMENTS' => urlencode('3')
);
Paypal Result:
[2016-04-12 12:50 America/New_York] Verified IPN:cmd=_notify-validate&
payment_cycle=Daily&
txn_type=recurring_payment_profile_created&
last_name=Mustermann&
next_payment_date=03%3A00%3A00+Apr+12%2C+2016+PDT&
residence_country=US&
initial_payment_amount=0.00&
currency_code=USD&
time_created=09%3A49%3A25+Apr+12%2C+2016+PDT&
verify_sign=AJjtUEC2-zvkp.2Yz8a-.FGmZ2b3AoUov3DJ70yddjCmc1KidQVDeZHd&
period_type=+Regular&
payer_status=verified&
test_ipn=1&
tax=0.00&
payer_email=gut%40gut.de&
first_name=Hendrik&
receiver_email=hendrik.tewes-facilitator%40live.de&
payer_id=6AJ2HHWAPZSF6&
product_type=1&shipping=0.00&
amount_per_cycle=119.00&
profile_status=Active&
charset=windows-1252&
notify_version=3.8&
amount=119.00&
outstanding_balance=0.00&
recurring_payment_id=I-8P0534LSX2A3&
product_name=FitnessMembership&
ipn_track_id=59fede576b95c
You can charge an initial amount when creating a Recurring Payment Profile for Express Checkout.
Here is the documentation from the PayPal Developer Site
In the CreateRecurringPaymentsProfile API call, you will need to use the variable INITAMT
Here is more information from the PayPal Developer Site:
INITAMT
(Optional) Initial non-recurring payment amount due immediately upon
profile creation. Use an initial amount for enrolment or set-up fees.
Note: All amounts included in the request must have the same currency.
Character length and limitations:
Value is typically a positive number which cannot exceed 10,000.00 USD
or the per transaction limit for the currency. It includes no currency
symbol. Most currencies require two decimal places; the decimal
separator must be a period (.), and the optional thousands separator
must be a comma (,). Some currencies do not allow decimals. See the
currency codes page for details.
Related
I'm having troubles with the PayPal callback feature, i can't for the life of me get it to work at all. I have double checked the callback URL path, it's correct. When the user logs into paypal, it always just returns the default shipping rate. I'm just really not sure what i am missing here, if anyone can help out. Also, i have the callback timeout set to 6, though it seems it only takes about 3 - 4 seconds for it to fail and return the default shipping rate.
I've followed the documentation here https://developer.paypal.com/docs/classic/express-checkout/integration-guide/ECInstantUpdateAPI/ and applied it to my website. I've also made sure i am logged into sandbox too.
SetExpressCheckout params:
// SetExpressCheckout
$params = array (
'METHOD' => 'SetExpressCheckout',
'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
'VERSION' => $version, // 124.0
'USER' => $paypal_user,
'PWD' => $paypal_password,
'SIGNATURE' => $signature,
'L_SHIPPINGOPTIONNAME0' => 'Flat',
'L_SHIPPINGOPTIONLABEL0' => 'N/A',
'L_SHIPPINGOPTIONAMOUNT0' => '6.99',
'L_SHIPPINGOPTIONISDEFAULT0' => 'true',
'PAYMENTREQUEST_0_INSURANCEOPTIONSOFFERED' => 'false',
'PAYMENTREQUEST_0_SHIPPINGAMT' => $shipping_default, // 6.99
'PAYMENTREQUEST_0_ITEMAMT' => $cart_total,
'PAYMENTREQUEST_0_AMT' => $cart_total + $shipping_default,
'MAXAMT' => $cart_total + 30, // 30 is the total possible shipping amount
'PAYMENTREQUEST_0_CURRENCYCODE' => $paypal_currency, // AUD
'RETURNURL' => $paypal_return,
'CANCELURL' => $paypal_cancel,
'CALLBACK' => 'HTTP://localhost/moes/php/paypal_callback_php.php',
'CALLBACKTIMEOUT' => 6,
'CALLBACKVERSION' => '61.0',
'ALLOWNOTE' => 1,
'PAYMENTREQUEST_0_INVNUM' => '123' /*$invoice_number*/,
'PAYMENTREQUEST_0_TAXAMT' => $tax, // 0.00
);
// List each product and add to exress check-out array
foreach ($paypal_products as $k => $product){
$params["L_PAYMENTREQUEST_0_NAME$k"] = $product['name'];
$params["L_PAYMENTREQUEST_0_AMT$k"] = number_format($product['price'],2);
$params["L_PAYMENTREQUEST_0_QTY$k"] = $product['qty'];
$params["L_PAYMENTREQUEST_0_NUMBER$k"] = $product['code'];
$params["L_PAYMENTREQUEST_0_DESC$k"] = '1';
/* Optional shipping options to calculate shipping costs on callback
Option weight (L_PAYMENTREQUEST_n_ITEMWEIGHTVALUEm, L_PAYMENTREQUEST_n_ITEMWEITHTUNITm)
Option height (L_PAYMENTREQUEST_n_ITEMHEIGHTVALUEm, L_PAYMENTREQUEST_n_ITEMHEIGHTUNITm)
Option length (L_PAYMENTREQUEST_n_ITEMLENGTHVALUEm, L_PAYMENTREQUEST_n_ITEMLENGTHUNITm)
Option width (L_PAYMENTREQUEST_n_ITEMWIDTHVALUEm, L_PAYMENTREQUEST_n_ITEMWIDTHUNITm)*/
}
Callback script:
<?php
// Populate variables into local variables
$method = $_POST['METHOD'];
$version = $_POST['CALLBACKVERSION'];
$token = $_POST['TOKEN'];
$currencycode = $_POST['CURRENCYCODE'];
$localecode = $_POST['LOCALECODE'];
$street = $_POST['SHIPTOSTREET'];
$street2 = $_POST['SHIPTOSTREET2'];
$city = $_POST['SHIPTOCITY'];
$state = $_POST['SHIPTOSTATE'];
$country = $_POST['SHIPTOCOUNTRY'];
$zip = $_POST['SHIPTOZIP'];
// Setting shipping rate based on country [Test only]
if ($country == "US"){
echo "METHOD=CallbackResponse&OFFERINSURANCEOPTION=false&L_SHIPPINGOPTIONNAME0=FLat&L_SHIPPINGOPTIONLABEL0=N/A&L_SHIPPINGOPTIONAMOUNT0=10.00&L_TAXAMT0=1.00&L_INSURANCEAMOUNT0=9.00&L_SHIPPINGOPTIONISDEFAULT0=true";
} else {
echo "METHOD=CallbackResponse&OFFERINSURANCEOPTION=false&L_SHIPPINGOPTIONNAME0=FLat&L_SHIPPINGOPTIONLABEL0=N/A&L_SHIPPINGOPTIONAMOUNT0=30.00&L_TAXAMT0=1.00&L_INSURANCEAMOUNT0=9.00&L_SHIPPINGOPTIONISDEFAULT0=true";
}
?>
I'm guessing i missing something fundamental here, or i'm going about it completely the wrong way.
The solution to my problem was :
localhost/moes/php/paypal_callback_php.php
Obviously PayPal can't send a HTTP request to 'localhost'. My WAMP server is not configured to be accessible over the internet.
I'm struggling to decide between Paypal NVP and REST APIs.
The REST API seems to be newer and better but I can't find a way to get customer details after a transaction occured.
Basically I want to set up a billing plan for recurring payments and then get customer details via API so they do not have to enter them through my website.
Paypal Express checkout seems to be what I should use here.
The NVP API offers a GetExpressCheckoutDetails method to get these details.
I didn't find something similar for the REST API.
Since the REST API seems to go through Express Checkout as well there should be a solution.
How can I get customer details after activating the billing agreement?
I ran into this same problem a month ago and after reading the docs, there's currently no way to accomplish this with the REST API. If there is a way, it's not documented.
The only way I found to do this is with the NVP API and possibly the SOAP API. The NVP API will give you back most of the fields that you want but if you've stored custom fields for a transaction, it will only give you 3 of the custom fields but not all of them (weird).
I haven't tried the NVP method GetExpressCheckoutDetails but I have used the GetTransactionDetails method. It will give you back the transaction details. It returns a text block that you must parse. Each field is URL encoded and separated by an ampersand. Here's an example in PHP:
<?php
// Get cURL resource
$ch = curl_init();
// Set url
curl_setopt($ch, CURLOPT_URL, 'https://api-3t.paypal.com/nvp/');
// Set method
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
// Set options
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Set headers
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/x-www-form-urlencoded; charset=utf-8",
]
);
// Create body
$body = [
"VERSION" => "204.0",
"METHOD" => "GetTransactionDetails",
"USER" => "nvp_api_username_here",
"PWD" => "nvp_api_password_here",
"SIGNATURE" => "nvp_api_signature_here",
"TRANSACTIONID" => "some_paypal_transaction_id_here",
];
$body = http_build_query($body);
// Set body
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
// Send the request and save response to $resp
$resp = curl_exec($ch);
if(!$resp) {
die('Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch));
} else {
parse_str($resp, $formated_response);
print_r($formated_response);
}
// Close request to clear up some resources
curl_close($ch);
Here's the formatted return body:
Array
(
[RECEIVERBUSINESS] => paypal_account_owner_email_address_here#test.com
[RECEIVEREMAIL] => paypal_account_owner_email_address_here#test.com
[RECEIVERID] => 1111111111111
[EMAIL] => buyers_email_address_here#test.com
[PAYERID] => 55551
[PAYERSTATUS] => verified
[COUNTRYCODE] => US
[BUSINESS] => buyers_business_name_here
[ADDRESSOWNER] => PayPal
[ADDRESSSTATUS] => None
[SALESTAX] => 0.00
[SHIPAMOUNT] => 0.00
[SHIPHANDLEAMOUNT] => 0.00
[SHIPDISCOUNT] => 0.00
[INSURANCEAMOUNT] => 0.00
[GIFTRECEIPT] => 0
[TIMESTAMP] => 2016-08-02T17:04:58Z
[CORRELATIONID] => 55552
[ACK] => Success
[VERSION] => 204.0
[BUILD] => 22386173
[FIRSTNAME] => Foo
[LASTNAME] => Bar
[TRANSACTIONID] => 55553
[TRANSACTIONTYPE] => webaccept
[PAYMENTTYPE] => instant
[ORDERTIME] => 2016-08-01T20:49:28Z
[AMT] => 1.00
[TAXAMT] => 0.00
[CURRENCYCODE] => USD
[PAYMENTSTATUS] => Completed
[PENDINGREASON] => None
[REASONCODE] => None
[SHIPPINGMETHOD] => Default
[PROTECTIONELIGIBILITY] => Ineligible
[PROTECTIONELIGIBILITYTYPE] => None
[L_QTY0] => 0
[L_TAXAMT0] => 0.00
[L_SHIPPINGAMT0] => 0.00
[L_HANDLINGAMT0] => 0.00
[L_CURRENCYCODE0] => USD
[L_OPTIONSNAME0] => first_custom_field_label_here
[L_OPTIONSVALUE0] => first_custom_field_value_here
[L_OPTIONSNAME1] => second_custom_field_label_here
[L_OPTIONSVALUE1] => second_custom_field_value_here
[L_OPTIONS1NAME0] => second_custom_field_label_here_duplicate
[L_OPTIONS1VALUE0] => second_custom_field_value_here_duplicate
[L_TAXABLE0] => false
[L_TAXRATE0] => 0.0
[L_AMT0] => 1.00
[INSURANCEOPTIONSELECTED] => 0
[SHIPPINGOPTIONISDEFAULT] => 0
)
Warning:
This only applies if you're storing custom fields in a PayPal transaction.
PayPal's NVP API only returns up to 3 custom fields for a transaction, even though you can store up to 7 custom fields in a transaction. Even crazier, one of the custom fields it returns is a duplicate of the second custom field. At least that's the case when I try to retrieve a custom fields from a transaction.
I want to create recurring profile using Direct Payment Method.
I have enabled Business Pro account in sandbox accounts like as shown below.
And here are the API Credentials.
And below is my source code that I am using to create a Recurring Profile.
$data = array(
'USER' => urlencode('tahir.jumpstart-facilitator_api1.nxvt.com'),
'PWD' => urlencode('BHVM3E9XSLAJP9PX'),
'SIGNATURE' => urlencode('AAYoJuE-6E-mj5oERynM8zN4s4OrAvfUS7h9g45hGPQmxWb5RJxdJEBp'),
'VERSION' => '69.0',
'METHOD' => urlencode('CreateRecurringPaymentsProfile'),
'PROFILESTARTDATE' => gmdate("Y-m-d\TH:i:s\Z"),
'DESC' => urlencode('RacquetClubMembership'),
'BILLINGPERIOD' => 'Month',
'BILLINGFREQUENCY' => 1,
'AMT' => 10,
'MAXFAILEDPAYMENTS' => 3,
'ACCT' => '4032030239913727',
'CREDITCARDTYPE' => 'VISA',
'CVV2' => '123',
'FIRSTNAME' => 'James',
'LASTNAME' => 'Smith',
'STREET' => 'FirstStreet',
'CITY' => 'SanJose',
'STATE' => 'CA',
'ZIP' => '95131',
'COUNTRYCODE' => 'US',
'CURRENCYCODE' => 'USD',
'EXPDATE' => '072021'
);
$fields_string = http_build_query($data);
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_URL, 'https://api-3t.sandbox.paypal.com/nvp');
curl_setopt($curl, CURLOPT_POSTFIELDS, $fields_string);
$response = curl_exec($curl);
echo '<pre>';
print_r($response);
die;
$err = curl_error($curl);
curl_close($curl);
But when I run above code it shows me below error message.
TIMESTAMP=2016%2d06%2d09T13%3a52%3a39Z&CORRELATIONID=77466c4ec86e5&ACK=Failure&VERSION=69%2e0&BUILD=22204133&L_ERRORCODE0=11586&L_SHORTMESSAGE0=DPRP is disabled&L_LONGMESSAGE0=DPRP is disabled for this merchant&L_SEVERITYCODE0=Error
I have searched all over the internet and only thing that they suggest is to enable Business Pro account that is already enabled and you can clearly see this in above screenshot.
I am now lost, would really appreciate if someone can tell me if there is some issue with above code or I am missing something?
Many Thanks!
Please submit a PayPal MTS ticket to help you grant the DPRP access.
My intention is to create a Recurring Profile and pass a company_id as custom parameter to be stored IPN database, where I can create a relation between payment and for which company it was done.
I have read that while creating Recurring Payment Profile to get some custom value in IPN database, you should pass it in PROFILEREFERENCE parameter and then retrieve it from rp_invoice_id in response.
I cannot get the desired output
My request:
$inputData = array(
'METHOD' => 'CreateRecurringPaymentsProfile',
'TOKEN' => $_GET['token'], //get from GetExpressCheckout
'PAYERID' => $billerInfo['PAYERID'], //from GetExpressCheckout response
'PROFILESTARTDATE' => date("Y-m-d h:i:s", strtotime("+5 seconds")), //2012-05-11T00:00:00Z #Billing date start, in UTC/GMT format
'DESC' => 'LeaveBuddy: subscription amount is $' . $bill .' for the provided service ($12 per user per year).', //#Profile description - same as billing agreement description
'BILLINGPERIOD' => 'Year', #Period of time between billings
'BILLINGFREQUENCY' => 1,#Frequency of charges
'AMT' => 10, //Todo: dynamically calculate the amt #The amount the buyer will pay in a payment period
'CURRENCYCODE' => 'USD',#The currency, e.g. US dollars
'COUNTRYCODE' => 'US',#The country code, e.g. US
'MAXFAILEDPAYMENTS' => '0',#Maximum failed payments before suspension of the profile
'PROFILEREFERENCE' => 'companyid=1', //my custom value
);
The response that I am getting is:
{"InstantPaymentNotification":{"id":"553db30b-ea1c-4f68-8b5d-4fe5cbdd56cb","notify_version":"3.8","verify_sign":"A--8MSCLabuvN8L.-MHjxC9uypBtAQZom1C7.mbS1Jv-J898ZO0eeOr9","test_ipn":"1","address_city":null,"address_country":null,"address_country_code":null,"address_name":null,"address_state":null,"address_status":null,"address_street":null,"address_zip":null,"first_name":"code","last_name":"booster","payer_business_name":null,"payer_email":"codebooster#gmail.com","payer_id":"XXXXXXXX","payer_status":"verified","contact_phone":null,"residence_country":"US","business":null,"item_name":null,"item_number":null,"quantity":null,"receiver_email":"boom#gmail.com","receiver_id":null,"custom":null,"invoice":null,"memo":null,"option_name1":null,"option_name2":null,"option_selection1":null,"option_selection2":null,"tax":"0.00","auth_id":null,"auth_exp":null,"auth_amount":null,"auth_status":null,"num_cart_items":null,"parent_txn_id":null,"payment_date":null,"payment_status":null,"payment_type":null,"pending_reason":null,"reason_code":null,"remaining_settle":null,"shipping_method":null,"shipping":"0.00","transaction_entity":null,"txn_id":"316859739","txn_type":"recurring_payment","exchange_rate":null,"mc_currency":null,"mc_fee":null,"mc_gross":10,"mc_handling":null,"mc_shipping":null,"payment_fee":null,"payment_gross":null,"settle_amount":null,"settle_currency":null,"auction_buyer_id":null,"auction_closing_date":null,"auction_multi_item":null,"for_auction":null,"subscr_date":null,"subscr_effective":null,"period1":null,"period2":null,"period3":null,"amount1":null,"amount2":null,"amount3":null,"mc_amount1":null,"mc_amount2":null,"mc_amount3":null,"recurring":null,"reattempt":null,"retry_at":null,"recur_times":null,"username":null,"password":null,"subscr_id":null,"case_id":null,"case_type":null,"case_creation_date":null,"created":"2015-04-27 03:54:51","modified":"2015-04-27 03:54:51"},"PaypalItem":[]}
So i cannot find any [rp_invoice_id] parameter here, and my invoice is also appearing null. Can any one tell me what I am missing?
Sure it's just something I'm missing. Fairly new to the Paypal API, especially the classic one! Basically, I'm using the following code to generate a subscription to my site at £2.50 per month. I can get the subscription to appear in the Recurring Payments Dashboard on Paypal Sandbox, but it doesn't change the balance and seems to be missing things to do with the initial payment. I tried INITAMT too, which filled in some fields, but still doesn't change the Sandbox balance of my account. Any ideas guys? Here's the code:
<?php
// Set PayPal API version and credentials.
$api_version = '85.0';
$api_endpoint = 'https://api-3t.sandbox.paypal.com/nvp';
$api_username = 'MY_SANDBOX_USERNAME';
$api_password = 'MY_SANDBOX_PASSWORD';
$api_signature = 'MY_SANDBOX_SIGNATURE';
$startdate = gmdate('Y-m-d')."T00:00:00Z";
$request_params = array
(
'USER' => $api_username,
'PWD' => $api_password,
'SIGNATURE' => $api_signature,
'VERSION' => $api_version,
'METHOD' => 'CreateRecurringPaymentsProfile',
'PROFILESTARTDATE' => $startdate,
'DESC' => 'Membership',
'BILLINGPERIOD' => 'Month',
'BILLINGFREQUENCY' => '1',
'TOTALBILLINGCYCLES' => '0',
'AMT' => '2.50',
'MAXFAILEDPAYMENTS' => '12',
'ACCT' => '4641631486853053',
'CREDITCARDTYPE' => 'VISA',
'CVV2' => '123',
'FIRSTNAME' => 'James',
'LASTNAME' => 'Smith',
'STREET' => 'FirstStreet',
'CITY' => 'London',
'STATE' => 'G London',
'ZIP' => 'W2 1NE',
'COUNTRYCODE' => 'GB',
'CURRENCYCODE' => 'GBP',
'EXPDATE' => '052015'
);
// Loop through $request_params array to generate the NVP string.
$nvp_string = '';
foreach($request_params as $var=>$val)
{
$nvp_string .= '&'.$var.'='.urlencode($val);
}
// Send NVP string to PayPal and store response
$curl = curl_init();
curl_setopt($curl, CURLOPT_VERBOSE, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_URL, $api_endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $nvp_string);
$result = curl_exec($curl);
curl_close($curl);
$nvp_response_array = parse_str($result);
print_r($result);
?>
I took your code and used my own sandbox credentials. It seems to have worked just fine for me.
It came through as unclaimed since my account is USD, but you can see it did work just fine. Are you sure you're checking the correct sandbox account after you run it yourself?