I'm using the following PHP code to encrypt the billing details I'm passing to PayPal:
<?php
$MY_KEY_FILE = "my-prvkey.pem";
$MY_CERT_FILE = "my-pubcert.pem";
$PAYPAL_CERT_FILE = "paypal_cert.pem";
$OPENSSL = "/usr/bin/openssl";
$form = array(
'cmd' => '_xclick',
'cert_id' => 'HSFU5KJLFS8JD',
'business' => 'example#icloud.com',
'currency_code' => 'EUR',
'no_shipping' => '1',
'charset' => 'utf-8',
'lc' => 'DE',
'item_name' => 'Test',
'amount' => '4.20',
'return' => 'http://www.example.com/success.php',
'cancel_return' => 'http://www.example.com/error.php',
);
$encrypted = paypal_encrypt($form);
function paypal_encrypt($hash)
{
global $MY_KEY_FILE;
global $MY_CERT_FILE;
global $PAYPAL_CERT_FILE;
global $OPENSSL;
if (!file_exists($MY_KEY_FILE)) {
echo "ERROR: MY_KEY_FILE $MY_KEY_FILE not found\n";
}
if (!file_exists($MY_CERT_FILE)) {
echo "ERROR: MY_CERT_FILE $MY_CERT_FILE not found\n";
}
if (!file_exists($PAYPAL_CERT_FILE)) {
echo "ERROR: PAYPAL_CERT_FILE $PAYPAL_CERT_FILE not found\n";
}
$data = "";
foreach ($hash as $key => $value) {
if ($value != "") {
$data .= "$key=$value\n";
}
}
$openssl_cmd = "($OPENSSL smime -sign -signer $MY_CERT_FILE -inkey $MY_KEY_FILE "."-outform der -nodetach -binary <<_EOF_\n$data\n_EOF_\n) | "."$OPENSSL smime -encrypt -des3 -binary -outform pem $PAYPAL_CERT_FILE";
exec($openssl_cmd, $output, $error);
if (!$error) {
return implode("\n",$output);
} else {
return "ERROR: encryption failed";
}
};
?>
<!DOCTYPE html>
<html>
<body>
<form action="https://www.paypal.com/cgi-bin/webscr" method="get">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="encrypted" value=" <?php echo $encrypted;?>">
<input type="submit">
</form>
</body>
</html>
When clicking on the submit button I'll get redirected to PayPal and can make the payment.
I can either send the form data with method="post" or method="get".
If I'm using my code with method="post" I'm getting redirected to a page looking like this:
When using exactly the same code but changing method="post" to method="get" I'm getting redirected to a page looking like this:
This doesn't really look beautiful. I prefer the first one and I think my customers will do so, too.
Does anybody know how I can fix that? What am I doing wrong?
I have seen your question on Freelancer website as well. For your requirement of HTTP GET:
PayPal is discontinuing use of HTTP GET from June 2017.
https://www.paypal.com/au/webapps/mpp/discontinuation-get-method
Related
I'm using coinpayment gateway api (cmd=create_transfer).
I generated qr code and address those are successfully scanned from app but after payment I want to redirect success_url and other information submitted into database.
<?php
/*
CoinPayments.net API Example
Copyright 2016 CoinPayments.net. All rights reserved.
License: GPLv2 - http://www.gnu.org/licenses/gpl-2.0.txt
*/
require('./coinpayments.inc.php');
$cps = new CoinPaymentsAPI();
$public_key = "xxx";
$private_key = "xxx";
$cps->Setup($private_key, $public_key);
$req = array(
'amount' => $_POST['amount'],
'currency1' => "USD",
'currency2' => "BTC",
'address' => '', // leave blank send to follow your settings on the Coin Settings page
// 'item_name' => $_POST['item_name']
print 'ipn_url' => $_POST['ipn_url'],
print 'txn_id' => $_POST['txn_id'],
print 'status' => intval($_POST['status']),
print 'status_text' => $_POST['status_text']
);
// See https://www.coinpayments.net/apidoc-create-transaction for all of the available fields
$result = $cps->CreateTransaction($req);
if ($result['error'] == 'ok') {
$le = php_sapi_name() == 'cli' ? "\n" : '<br />';
?>
<div class="col-4">
<h2><?php print 'Buyer should send ' . sprintf('%.08f', $result['result']['amount']) . ' BTC' . $le; ?></h2>
<img width="220" height="220" alt="" src="https://blockchain.info/qr?data=bitcoin:<?php echo $result['result']['address']; ?>?amount=<?php echo $result['result']['amount']; ?>%26label=example%2520label">
<?php
} else {
print 'Error: ' . $result['error'] . "\n";
}
?>
Please refer here :- https://www.coinpayments.net/apidoc-get-tx-info. To make use of this api, just add this function in coinpayments.inc.php
}
public function GetTransactionInformation($txId) {
$req = array(
'txid' => $txId,
);
return $this->api_call('get_tx_info', $req);
}
Add this in you's script before printing tx id
$txid = strip_tags($_POST['txn_id'])
And for results
$cps = new CoinPaymentsAPI();
$cps->Setup('Your_Private_Key', 'Your_Public_Key');
$result = $cps->GetTransactionInformation('$txid');
//get the array info of transaction
if ($result['error'] == 'ok') {
print_r ($result);
} else {
print 'Error: '.$result['error']."\n";
}
You should get result in Array. For getting in Json output just replace.
print_r ($result);
With
print $result['result']['status']
Replace status with other arrays and modify your page accordingly.
Status has following numericals:-
<0 Error, 0-99 Pending, 100 Completed/Paid
If you are wanting offsite checkout you'd want to be using the Simple or Advanced buttons, the 'create_transaction' API is for making your own custom checkout pages.
Please check this link for the Simple or Advanced buttons:
Coinpayments Simple and Advanced buttons link.
I have some code here that is not functioning.
The critical issue here is the SSL encryption through the exec command in PHP.
The part <<EOF\n$data\n_EOF_\n is causing an issue as it causes the encryption to fail. I have tried the rest of the command without <<EOF\n$data\n_EOF_\n and it worked fine.
Notes:
I am running on Windows 10, XAMPP Control Panel v3.2.2, PHP, and Apache.
This is a personal computer.
It has the full installation of XAMPP.
OpenSSL is enabled.
PHP safe_mode is disabled.
The paths of OpenSSL and the certificate files are correct.
I have done much research into this issue and could not quite find a reliable solution. I would greatly appreciate some help! Thanks!
$types = array('bronze','silver','gold','platinum','diamond');
if(!in_array($_GET['type'],$types)) {
die('<error />');
}
$type = $_GET['type'];
if($type == 'bronze') {
$amount = '15.00';
} elseif ($type == 'silver') {
$amount = '25.00';
} elseif ($type == 'gold') {
$amount = '50.00';
} elseif ($type == 'platinum') {
$amount = '75.00';
} elseif ($type == 'diamond') {
$amount = '100.00';
}
#Discount Rate
$discount_rate = '0';
$IPN_URL = 'https://www.example.net/paypal/ipn';
$PAYPAL_CERT_FILE = 'C:\\xampp\\example.net\\paypal\\paypal_cert.pem';
$MY_KEY_FILE = 'C:\\xampp\\example.net\\paypal\\prvkey.pem';
$MY_CERT_FILE = 'C:\\xampp\\example.net\\paypal\\pubcert.pem';
$OPENSSL = 'C:\\xampp\\apache\\bin\\openssl.exe';
$form = array(
'cmd' => '_xclick',
'amount' => $amount,
'item_number' => explode('"',$userinfo['external_auth'])[3],
'discount_rate' => $discount_rate,
'item_name' => ucfirst($type).' EXAMPLE :: TEST',
'notify_url' => $IPN_URL,
'business' => 'example#live.ca',
'cert_id' => 'SOME_ID_HERE',
'currency_code' => 'USD',
'no_shipping' => '1'
);
function paypal_encrypt($hash) {
global $MY_KEY_FILE;
global $MY_CERT_FILE;
global $PAYPAL_CERT_FILE;
global $OPENSSL;
if (!file_exists($MY_KEY_FILE)) {
echo "ERROR: MY_KEY_FILE $MY_KEY_FILE not found\n";
}
if (!file_exists($MY_CERT_FILE)) {
echo "ERROR: MY_CERT_FILE $MY_CERT_FILE not found\n";
}
if (!file_exists($PAYPAL_CERT_FILE)) {
echo "ERROR: PAYPAL_CERT_FILE $PAYPAL_CERT_FILE not found\n";
}
//Assign Build Notation for PayPal Support
$hash['bn']= 'domain.PHP_EWP2';
$data = "";
foreach ($hash as $key => $value) {
if ($value != "") {
$data .= "$key=".escapeshellcmd($value)."\n";
}
}
$openssl_cmd = "($OPENSSL smime -sign -signer $MY_CERT_FILE -inkey $MY_KEY_FILE " .
"-outform der -nodetach -binary <<_EOF_\n$data\n_EOF_\n) | " .
"$OPENSSL smime -encrypt -des3 -binary -outform pem $PAYPAL_CERT_FILE";
exec($openssl_cmd, $output, $error);
if (!$error) {
return implode("\n",$output);
} else {
return "ERROR: encryption failed";
}
};
$encrypted = paypal_encrypt($form);
die('<success />'.$encrypted);
EDIT:
I am using https://www.stellarwebsolutions.com/en/articles/paypal_button_encryption_php.php as a guide.
If you are using xampp and your notify url has "localhost" in it, you are on another level. If you have a domain masking your xampp server, u can't use that url. Your notify url has to be ip address. ;) Just know I came back to tell you that. Just figured it out myself. If it helped, donate to foziazzubaidi#gmail.com through paypal haha. If it didn't, I've been making websites for a decade now. Send me an email, I'd be happy to help.
PEACE!!!
Currently I'm using PayPal buttons for receiving payments from users. I have a website that automatically calculates postage cost for a particular item, and I want to update the cost on the PayPal page to reflect the shipping costs. How do I accomplish this?
I'm thinking there should be a way to dynamically create an encrypted PayPal "Buy Now" button in PayPal, then display that form to the user, but the documentation on how to do this is scattered.
If possible I want to avoid recording transactions in a database and verifying. I just want a PayPal button that I can securely change the shipping cost of, disallowing users from setting the cost manually.
Create PayPal certificates following instructions: https://developer.paypal.com/docs/classic/paypal-payments-standard/integration-guide/encryptedwebpayments/#id08A3I0P20E9
In PHP:
define('OPENSSL', '/usr/bin/openssl');
class PayPal {
public function __construct() {
$this->key_file = 'my-prvkey.pem';
$this->cert_file = 'my?pubcert.pem';
$this->paypal_key = 'paypal_cert.pem';
$this->button = array(
'cert_id' => 'YOUR CERT ID',
'cmd' => '_xclick',
'business' => 'YOUR PAYPAL EMAIL',
'lc' => 'US',
'item_name' => 'ITEM NAME',
'amount' => 'X',
'currency_code' => 'USD',
'button_subtype' => 'services',
'no_note' => '0',
'bn' => 'PP-BuyNowBF:btn_buynow_LG.gif:NonHostedGuest'
);
}
public function create_form($shipping) {
$this->button['shipping'] = $shipping;
return '<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top"><input name="cmd" type="hidden" value="_s-xclick" />
<input name="encrypted" type="hidden" value="'.$this->encrypt().'" />
<input type="image" src="https://www.paypalobjects.com/en_AU/i/btn/btn_buynow_LG.gif" border="0" name="submit" alt="PayPal — The safer, easier way to pay online.">
<img src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" alt="" width="1" height="1" border="0" /></form>';
}
private function encrypt() {
$data = '';
foreach ($this->button as $key => $value) {
if ($value) $data .= "$key=$value\n";
}
$cmd = '('.OPENSSL." smime -sign -signer {$this->cert_file} -inkey {$this->key_file} " .
"-outform der -nodetach -binary <<_EOF_\n{$data}\n_EOF_\n) | " .
OPENSSL." smime -encrypt -des3 -binary -outform pem {$this->paypal_key}";
exec($cmd, $output, $error);
return implode("\n", $output);
}
}
Then to output the dynamic PayPal form:
$paypal = new Paypal();
echo $paypal->create_form(20);
Consider using braintree which was acquired by PayPal for a more simplified PayPal implementation.
To answer your question, you should have the postage calculation occur before sending the purchase data to PayPal so that the user confirms the final amount.
I'm unfamiliar with the buttons but their implementation needs to allow for shipping costs to fluctuate.
Obviously PayPal will not allow a price change after the user has confirmed a lower/different price.
I think I asked this twice already and no one even bothered to view this. please help me out and try to at least think about it before forgetting the question.
So I am following this tutorial : http://www.stellarwebsolutions.com/en/articles/paypal_button_encryption_php.php and when I used their code and inserted all the things that were different with me I ran the code and got the error message from paypal 'Unable to decrypt certificate id'. After a little of research I found that the function in the code returned 'ERROR: Encryption failed.' I think the error was caused by the following piece of code:
$openssl_cmd = "($OPENSSL smime -sign -signer $MY_CERT_FILE -inkey $MY_KEY_FILE " .
"-outform der -nodetach -binary < \"_EOF_\n$data\n_EOF_\n\") | " .
"$OPENSSL smime -encrypt -des3 -binary -outform pem $PAYPAL_CERT_FILE";
exec($openssl_cmd, $output, $error);
if (!$error) {
return implode("\n",$output);
} else {
return "ERROR: encryption failed";
}
Is there any possible way of converting this openssl command to a openssl_something(); call? I would greatly appreciate any help. Here is the full code and another note: PLEASE don't make stupid comments on themes such as the questions is bad, e.t.c. :
<?php
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(-1);
?>
<HTML>
<?php
//Sample PayPal Button Encryption: Copyright 2006-2010 StellarWebSolutions.com
//Not for resale - license agreement at
//http://www.stellarwebsolutions.com/en/eula.php
//Updated: 2010 02 01
# private key file to use
$MY_KEY_FILE = "my-prvkey.pem";
# public certificate file to use
$MY_CERT_FILE = "my-pubcert.pem";
# Paypal's public certificate
$PAYPAL_CERT_FILE = "paypal_cert_pem.txt";
# path to the openssl binary
$OPENSSL = "/usr/bin/openssl";
$form = array('cmd' => '_xclick',
'business' => 'naclo3samuel#gmail.com',
'cert_id' => 'PRIVACY?',
'lc' => 'RU',
'custom' => 'test',
'invoice' => '',
'currency_code' => 'USD',
'no_shipping' => '1',
'item_name' => 'Donation',
'item_number' => '1',
'amount' => '10'
);
$encrypted = paypal_encrypt($form);
function paypal_encrypt($hash)
{
//Sample PayPal Button Encryption: Copyright 2006-2010 StellarWebSolutions.com
//Not for resale - license agreement at
//http://www.stellarwebsolutions.com/en/eula.php
global $MY_KEY_FILE;
global $MY_CERT_FILE;
global $PAYPAL_CERT_FILE;
global $OPENSSL;
if (!file_exists($MY_KEY_FILE)) {
echo "ERROR: MY_KEY_FILE $MY_KEY_FILE not found\n";
}
if (!file_exists($MY_CERT_FILE)) {
echo "ERROR: MY_CERT_FILE $MY_CERT_FILE not found\n";
}
if (!file_exists($PAYPAL_CERT_FILE)) {
echo "ERROR: PAYPAL_CERT_FILE $PAYPAL_CERT_FILE not found\n";
}
//Assign Build Notation for PayPal Support
$hash['bn']= 'StellarWebSolutions.PHP_EWP2';
$data = "";
foreach ($hash as $key => $value) {
if ($value != "") {
//echo "Adding to blob: $key=$value\n";
$data .= "$key=$value\n";
}
}
$openssl_cmd = "($OPENSSL smime -sign -signer $MY_CERT_FILE -inkey $MY_KEY_FILE " .
"-outform der -nodetach -binary < \"_EOF_\n$data\n_EOF_\n\") | " .
"$OPENSSL smime -encrypt -des3 -binary -outform pem $PAYPAL_CERT_FILE";
exec($openssl_cmd, $output, $error);
if (!$error) {
return implode("\n",$output);
} else {
return "ERROR: encryption failed";
}
};
?>
<HEAD>
<LINK REL=stylesheet HREF="/styles/stellar.css" TYPE="text/css">
<TITLE>PHP Sample Donation using PayPal Encrypted Buttons</TITLE>
</HEAD>
<BODY bgcolor=white>
<TABLE border=0>
<TR><TD align=center>
<h1>Sample Donation Page</h1>
<P>This page uses encrypted PayPal buttons for your security.</P>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target=_blank>
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="encrypted" value="
<?PHP echo $encrypted; ?>">
<input type="submit" value="Donate $10">
</form>
<P><SMALL>(PayPal will open in a new window for demonstration purposes.)</SMALL></P>
</TD></TR></TABLE>
</BODY>
</HTML>
Well, then here is my answer ;) You might have a problem with safe_mode which prevents your code from executing the openssl binary.
Attempting to use dynamic encryption for Paypal on my local WAMP 2.4 server. Openssl is installed in Apache and enabled in PHP. Using exec Openssl fails. Can anyone provide some suggestions or if you feel real generous the code for converting the following PHP code to PHP Openssl requests (preferred method)? BTW I've tried both OPENSSL file pointers, both are found but neither works.
function paypal_encrypt($hash)
{
//Sample PayPal Button Encryption: Copyright 2006-2010 StellarWebSolutions.com
//Not for resale - license agreement at
//http://www.stellarwebsolutions.com/en/eula.php
$MY_KEY_FILE='paypal/encrypt/myprivate_key.pem';
$MY_CERT_FILE='paypal/encrypt/mypublic_cert.pem';
$PAYPAL_CERT_FILE='paypal/encrypt/paypal_cert.pem';
$OPENSSL='../../bin/apache/Apache2.4.4/bin/openssl.exe';
$OPENSSL='../../bin/apache/Apache2.4.4/conf/openssl.cnf';
if (!file_exists($MY_KEY_FILE)) {
echo "ERROR: MY_KEY_FILE $MY_KEY_FILE not found\n";
}
if (!file_exists($MY_CERT_FILE)) {
echo "ERROR: MY_CERT_FILE $MY_CERT_FILE not found\n";
}
if (!file_exists($PAYPAL_CERT_FILE)) {
echo "ERROR: PAYPAL_CERT_FILE $PAYPAL_CERT_FILE not found\n";
}
if (!file_exists($OPENSSL)) {
echo "ERROR: Openssl $OPENSSL not found\n";
}
//Assign Build Notation for PayPal Support
$hash['bn']= 'StellarWebSolutions.PHP_EWP2';
$data = "";
foreach ($hash as $key => $value) {
if ($value != "") {
//echo "Adding to blob: $key=$value\n";
$data .= "$key=$value\n";
}
}
echo $data;
$openssl_cmd = "($OPENSSL smime -sign -signer $MY_CERT_FILE -inkey $MY_KEY_FILE " .
"-outform der -nodetach -binary <<_EOF_\n$data\n_EOF_\n) | " .
"$OPENSSL smime -encrypt -des3 -binary -outform pem $PAYPAL_CERT_FILE";
exec($openssl_cmd, $output, $error);
if (!$error) {
return implode("\n",$output);
} else {
return $error."ERROR: encryption failed";
}
}
I have successfully done it with couple of hours of trying and searching. Finally found this very helpful article
Simplified Code Below
function paypal_ewp_encrypt_data( $hash, $certs ){
$temp_files_dir_path = ''; // a directory php have write access where we will write temporary files and delete afterwards.
$data = 'cert_id=' . $certs->paypal_cert_id;
foreach ($hash as $key => $value) {
if ($value != "") {
$data .= "\n$key=$value";
}
}
$unique_id = uniqid(time());
$data_file_in = $temp_files_dir_path . DIRECTORY_SEPARATOR . $unique_id . "-data-in.txt"; // raw data fie
$data_file_out = $temp_files_dir_path . DIRECTORY_SEPARATOR . $unique_id . "-data-out.txt";// signed data file
$enc_file_out = $temp_files_dir_path . DIRECTORY_SEPARATOR . $unique_id . "-enc-out.txt"; // encrypted data file
$fp = fopen( $data_in, "w" );
fwrite($fp, $data);
fclose($fp);
if( ! openssl_pkcs7_sign(
$data_file_in, $data_file_out, 'file://' . $certs->public_key,
array( 'file://' . $certs->private_key, ''),
array(),
PKCS7_BINARY)
){
return false;
}
$data_out_data = explode("\n\n", file_get_contents($data_out));
$out = fopen($data_out, 'wb');
fwrite($out, base64_decode($data_out_data[1]));
fclose($out);
if( ! openssl_pkcs7_encrypt(
$data_file_out, $enc_file_out,
'file://' . $certs->paypal_public_key, array(),
PKCS7_BINARY, OPENSSL_CIPHER_3DES )
){
return false;
}
$en_data = explode("\n\n", file_get_contents($enc_file_out) );
$en_data = $en_data[1];
$en_data = "-----BEGIN PKCS7-----" . str_replace("\n", "", $en_data ) . "-----END PKCS7-----";
// delete files
#unlink($data_file_in);
#unlink($data_file_out);
#unlink($enc_file_out);
$paypal_array = array(
'cmd' => '_s-' . $hash['cmd'], // use _s- before the cmd
'encrypted' => $en_data
);
}
function certs(){
$certs = new stdClass();
$certs->public_key = '' // absolute path to your public key file
$certs->private_key = '' // absolute path to your private key file
$certs->paypal_public_key = '' // absolute path to paypal public key file
$certs->paypal_cert_id = '' // given cert id after you upload the public key to paypal website.
}
Implementation
$hash = array(
// key value pair of paypal form variables
);
$certs = certs();
$data = paypal_ewp_encrypt_data($hash, $certs);
Data is a php array of key value pair require to create the form fields. Use key as name and value as field value.