I am integrating authorize.net in PHP. I have used http://developer.authorize.net/integration/fifteenminutes/#custom this sdk for my development.
For testing, I have created an sandbox account. When I am executing the code - I'm getting below error:-
AuthorizeNet Error: Response Code: 3
Response Subcode: 1
Response Reason Code: 87
Response Reason Text: (TESTMODE) Transactions of this market type cannot be processed on this system.
How will I recover this issue and will make an successful test?
I have also checked payment processing using authorize.net. But not helped me so much.
Any help is appreciated.
EDIT:- code is below
function authorizeNet($options)
{
require_once '../anet_php_sdk/AuthorizeNet.php'; // Make sure this path is correct.
$transaction = new AuthorizeNetAIM('YOUR_API_LOGIN_ID', 'YOUR_TRANSACTION_KEY');
$transaction->amount = $options["gift_amt"];
$transaction->card_num = $options["card_no"];
$transaction->exp_date = $options["card_expiry"];
$response = $transaction->authorizeAndCapture();
if ($response->approved) {
echo "<h1>Success! The test credit card has been charged!</h1>";
echo "Transaction ID: " . $response->transaction_id;
die();
} else {
echo $response->error_message;
die();
}
}
in the place of YOUR_API_LOGIN_ID and YOUR_TRANSACTION_KEY - I placed correct information. Here I don't want to disclose so I haven't mentioned it here.
This error indicates that the account that you are using was created for Card Present (retail) transactions, but you are trying to integrate to our Card Not Present (e-commerce) APIs or vice versa. The only way to resolve this is to open a new sandbox account with the correct market type.
Related
I'm using PHP UPS API (https://github.com/gabrielbull/php-ups-api) to get rates and to hopefully generate labels.
I've logged into UPS and set up credentials. I have Client Id and Client Secret and successfully generated my access_token via curl. I have endpoints set up for testing and production and things seem to be working fine, until I try to issue a Rate call
$shipFrom and $shipTo are set up properly...
try {
$shipment = new \Ups\Entity\Shipment();
$shipFrom = new \Ups\Entity\ShipFrom();
$shipFrom->setAddress($address_from);
$shipment->setShipFrom($shipFrom);
$shipTo = $shipment->getShipTo();
$shipTo = $shipTo->setAddress($address_to);
$package = new \Ups\Entity\Package();
$package->getPackagingType()->setCode(\Ups\Entity\PackagingType::PT_PACKAGE);
$package->getPackageWeight()->setWeight($weight);
// if you need this (depends of the shipper country)
$weightUnit = new \Ups\Entity\UnitOfMeasurement;
$weightUnit->setCode(\Ups\Entity\UnitOfMeasurement::UOM_LBS);
$package->getPackageWeight()->setUnitOfMeasurement($weightUnit);
$dimensions = new \Ups\Entity\Dimensions();
$dimensions->setHeight($height);
$dimensions->setWidth($width);
$dimensions->setLength($length);
$unit = new \Ups\Entity\UnitOfMeasurement;
$unit->setCode(\Ups\Entity\UnitOfMeasurement::UOM_IN);
$dimensions->setUnitOfMeasurement($unit);
$package->setDimensions($dimensions);
$shipment->addPackage($package);
var_dump($rate->getRate($shipment));
} catch (Exception $e) {
var_dump($e);
}
The exception is caught and I see this:
object(Ups\Exception\InvalidResponseException)#31 (7) {
["message":protected]=>
string(47) "Failure: Invalid Access License number (250003)"
This object is requiring $accessKey, $userId, $password.
I was assuming $accessKey would be my $accessToken. I'm believing that is incorrect. So where can I get an access key?
When I go here:
https://www.ups.com/dpui/upsdeveloperkit?loc=en_US
When I select: "I want to integrate UPS technology into my business"
It will only have the text below available:
"Note: We are excited to show you our new Developer Portal where you can get OAuth credentials to integrate with our APIs. Please click here to get started"
When I click 'get started', I'm back to my developer portal
https://developer.ups.com/en-us/
If I click on Apps -> My App Name, I see the id and secret again. Nothing mentioning access key.
I feel like I'm missing a major step somewhere.
I'm trying to integrate Stripe to accept payments on a website. I've come to the point where pretty much everything works from the client's perspective - test payments go through, everything is integrated and I can do stuff on payment intent succeeded (on the client). However, I can only detect that on the front-end.
Now, I want to show customer some sensitive data when payment is completed. I can't do it on front end - because then client does not even have to pay for that. I need to use webhooks.
So, I've created a sample webhook like this:
require_once 'stripe-php-7.97.0/init.php';
$endpoint_secret = 'endpoint_secret_code';
$payload = #file_get_contents('php://input');
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = null;
try {
$event = \Stripe\Webhook::constructEvent(
$payload, $sig_header, $endpoint_secret
);
} catch(\UnexpectedValueException $e) {
// Invalid payload
http_response_code(400);
exit();
} catch(\Stripe\Exception\SignatureVerificationException $e) {
// Invalid signature
http_response_code(400);
exit();
}
ob_flush();
ob_start();
var_dump($event);
file_put_contents("dump.txt", ob_get_flush());
// Handle the event
switch ($event->type) {
case 'payment_intent.succeeded':
$paymentIntent = $event->data->object;
var_dump($event->type);
// ... handle other event types
default:
echo 'Received unknown event type ' . $event->type;
}
http_response_code(200);
I've also created a webhook in the Stripe dashboard, like this:
However, based on the payment amount, I need to do something on this web hook - create a session, store data into the database and so on and so on. I've made it possible with Stripe CLI to test this webhook. However, how to test it using the test payments on the actual page? I have no idea how to do that - it does not work at the moment and without it, I can't be sure that it will work properly once everything goes live until I properly test it like this.
Does anyone have any tips, tutorials, or any kind of help to solve this? I'm pretty much stuck on it so any help would be greatly appreciated.
I'm having trouble trying to verify paypal webhook signatures with PHP. Using the new V2 of paypals APIs I am receiving the paypal webhook on my page.
However I can not seem to successfully validate the signature.
From the link HERE I got some sample webhook validation PHP code from paypal.
I can not get it working, I don't know where I am supposed to get bootstrap.php from in the paypal code. The paypal information seems incomplete or half baked. Paypal seems to be terrible to set-up compared to Stripe.
Has anyone got experience of validating paypal webhook signatures with PHP when using V2 of the paypal APIs ?
Well I have come to the conclusion that the Paypal developer information is rather poor, it is scatted all over the place, on multiple different pages and sites. The examples they give on the paypal developer website HERE are not a complete picture of what is required to validate a webhook signature. Stripe developer documentation is much better formatted and concise.
Installing Paypal Checkout V2 SDK does not give you the necessary development tools to validate paypal webhook signatures i.e. you can process payments and receive webhooks but you can not validate the webhook signatures....I know stupid. Tip do not download the SDK directly as you will not include the required autoload.php file. Use composer to install Paypal Checkout V2 SDK so that you get the autoload.php file.
Once you are to a point that you can process payments and receive webhooks form paypal you need to install the another SKD called Paypal Rest API SDK. Again use composer to install the SDK so that you get a autoload.php file which you will need.
When you install Paypal Rest API SDK amazingly you will still be missing files that are required to validate the payapl webhook signatures. I can find no mention of these anywhere on the paypal developer website.
bootstrap.php & common.php
Thanks to #Grumpy I got some samples provided on github HERE
Note you will probably need to modify the samples a bit in order to get them working with your website. Tip set the logger to false and save yourself some bother if you don't have the necessary access permissions to write.
Once you have bootstrap.php & common.php files created you can write the code for your webhook endpoint page i.e. the page that paypal sends the webhook to. I have included my PHP code below for how to validate and then process the paypal webhook. Tip in the below code you need to specify the webhook ID, each webhook that you create in paypal has a unique ID. Also when you are testing you can not use webhook simulator as this will fail validation, you can make manually a payment with your sandbox account details which will trigger a webhook payment event.
Paypal sure don't make it easy, their documentation is all over the place compared to Stripe. The Paypal webhooks can sometimes take several minutes to arrive after a payment is made, very frustrating when trying to debug. Also it's a bit ridiculous that they have a webhook simulator on the paypal developer website that can not be used to validate signatures...if stripe can do it why can't paypal.
<?php
//get the webhook payload
$requestBody = file_get_contents('php://input');
//check if webhook payload has data
if($requestBody) {
//request body is set
} else {
//request body is not set
exit();
}
use \PayPal\Api\VerifyWebhookSignature;
use \PayPal\Api\WebhookEvent;
$apiContext = require __DIR__ . '/bootstrap.php';
//Receive HTTP headers that you received from PayPal webhook.
$headers = getallheaders();
//need header keys to be UPPERCASE
$headers = array_change_key_case($headers, CASE_UPPER);
/*
example header paypal signature content for webhook, these values are recieved as an array, we then need to use this data to verify the payload
CONTENT-LENGTH : 1376
CORRELATION-ID : 6db85170269e7
USER-AGENT : PayPal/AUHD-214.0-54377828
CONTENT-TYPE: application/json
PAYPAL-AUTH-ALGO : SHA256withRSA
PAYPAL-CERT-URL : https://api.paypal.com/v1/notifications/certs/CERT-360caa42-fca2a784-5edc0ebc
PAYPAL-AUTH-VERSION : v2
PAYPAL-TRANSMISSION-SIG : Hc2lsDedYdSjOM4/t3T/ioAVQqFPNVB/AY/EyPNlavXk5WYUfnAmt9dyEP6neAPOjFHiVkXMK+JlLODbr6dalw6i26aFQdsPXqGl38Mafuu9elPE74qgsqNferUFgHi9QFXL+UZCNYcb4mvlDePXZIIAPbB0gOuFGOdEv2uqNwTCSAa/D8aguv1/51FWb3RkytFuVwXK/XNfIEy2oJCpDs8dgtYAZeojH8qO6IAwchdSpttMods5YfNBzT7oCoxO80hncVorBtjj1zQrkoynEB9WNNN9ytepNCkT8l29fQ4Sx/WRndm/PESCqxqmRoYJoiSosxYU3bZP7QTtILDykQ==
PAYPAL-TRANSMISSION-TIME : 2020-04-05T14:40:43Z
PAYPAL-TRANSMISSION-ID : 6dec99b0-774b-11ea-b306-c3ed128f0c4b
*/
//if any of the relevant paypal signature headers are not set exit()
if(
(!array_key_exists('PAYPAL-AUTH-ALGO', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-ID', $headers)) ||
(!array_key_exists('PAYPAL-CERT-URL', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-SIG', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-TIME', $headers))
)
{
exit();
}
//specify the ID for the webhook that you have set up on the paypal developer website, each web hook that you create has a unique ID
$webhookID = "ENTER_YOUR_WEBHOOK_ID_HERE";
//start paypal webhook signature validation
$signatureVerification = new VerifyWebhookSignature();
$signatureVerification->setAuthAlgo($headers['PAYPAL-AUTH-ALGO']);
$signatureVerification->setTransmissionId($headers['PAYPAL-TRANSMISSION-ID']);
$signatureVerification->setCertUrl($headers['PAYPAL-CERT-URL']);
$signatureVerification->setWebhookId($webhookID);
$signatureVerification->setTransmissionSig($headers['PAYPAL-TRANSMISSION-SIG']);
$signatureVerification->setTransmissionTime($headers['PAYPAL-TRANSMISSION-TIME']);
$signatureVerification->setRequestBody($requestBody);
$request = clone $signatureVerification;
try {
$output = $signatureVerification->post($apiContext);
} catch (Exception $ex) {
//error during signature validation, capture error and exit
ResultPrinter::printError("Validate Received Webhook Event", "WebhookEvent", null, $request->toJSON(), $ex);
exit(1);
}
$sigVerificationResult = $output->getVerificationStatus();
// $sigVerificationResult is a string and will either be "SUCCESS" or "FAILURE"
//if not webhook signature failed validation exit
if($sigVerificationResult != "SUCCESS"){
exit();
}
else if($sigVerificationResult == "SUCCESS"){
//paypay webhook signature is valid
//proceed to process webhook payload
//decode raw request body
$requestBodyDecode = json_decode($requestBody);
//pull whatever info required from decoded request body, some examples below
$paymentSystemID = $requestBodyDecode->id;
$eventType = $requestBodyDecode->event_type;
//do something with info captured from the webhook payload
}
This seems to work with php 8.1:
if (openssl_verify(
data: implode(separator: '|', array: [
$httpPayPalTransmissionId,
$httpPayPalTransmissionTime,
$webhookID,
crc32(string: $rawRequestBody),
]),
signature: base64_decode(string: $httpPayPalTransmissionSignature),
public_key: openssl_pkey_get_public(public_key: file_get_contents(filename: $cachedHttpPayPalCertUrl)),
algorithm: 'sha256WithRSAEncryption'
) === 1) {
die('OK');
} else {
die('FAILED');
}
I am using Paypal PHP Rest API from here for credit card payment. I can pay successfully with demo data. In real time when a user faces error in credit card payment, I need a way to show it in a user-friendly way rather than in a programmatic way.
From the paypal developer site , I found the format of the error object returned but cannot figure out how to use that.
My code follows:
try {
$payment->create($apiContext);
} catch (PayPal\Exception\PPConnectionException $ex) {
echo "Exception: " . $ex->getMessage() . PHP_EOL;
var_dump($ex->getData());
}
With intentional input of wrong data, following error message was there:
Exception: Got Http response code 400 when accessing
https://api.sandbox.paypal.com/v1/payments/payment.
string '{"name":"VALIDATION_ERROR","details":
[{"field":"payer.funding_instruments[0].credit_card",
"issue":"Invalid expiration (cannot be in the past)"},
{"field":"payer.funding_instruments[0].credit_card.number",
"issue":"Value is invalid"},{"field":
"payer.funding_instruments[0].credit_card.cvv2",
"issue":"Length is invalid (must be 3 or 4,
depending on card type)"}],"message":"Invalid request
- see details","information_link":
"https://developer.paypal.com/webapps
/developer/docs/api/#VALIDATION_ERROR","debug_id":
"bdcc'... (length=523)
So how can I get the error object as said in the mentioned Paypal developer site and how to use that to show errors to a non-techie person?
The error returned is in JSON format. You can use json_decode to decode it in PHP:
$error_object = json_decode($ex->getData());
switch ($error_object->name)
{
case 'VALIDATION_ERROR':
echo "Payment failed due to invalid Credit Card details:\n";
foreach ($error_object->details as $e)
{
echo "\t" . $e->field . "\n\t" . $e->issue . "\n\n";
}
break;
}
Add whichever cases you would like to your switch. And you can add your own flair, parse the $e->field and $e->issue to display whatever you like, etc.
I'm designing a website for a charity board game event, wherein people can watch the event live, and can donate money to a charity (Child's Play) in order to force players to play continuously for 60 hours. Because the donations are going directly to Child's Play, I need to use the notify_url setting to pass my IPN notification URL in; we've done this marathon twice before and have had no problems, but we recently ported it over to PHP.
Now, I've been testing the site extensively for the past few months using the sandbox, and everything was working perfectly. The marathon is only a couple of weeks away now, so I switched over to the actual PayPal system, fired off a test donation, and now I've got a problem: for some reason, PayPal is not hitting the notify_url at all. I've verified the URL by switching back to sandbox temporarily, and everything works fine. I've also added a few calls to error_log in the listener code to see if it's just getting caught in the code somewhere, but have found out it hasn't been hit at all.
If anyone can offer any suggestions here as to what I can do, I'd greatly appreciate it. Obviously I'm under a bit of a time crunch, so I'd really appreciate it if you could respond sooner rather than later.
EDIT: Here's the relevant code:
if (isset($_GET['paypalipn'])) {
// tell PHP to log errors to ipn_errors.log in this directory
ini_set('log_errors', true);
ini_set('error_log', dirname(__FILE__).'/ipn_errors.log');
// intantiate the IPN listener
$listener = new IpnListener();
// tell the IPN listener to use the PayPal test sandbox
$listener->use_sandbox = false;
error_log("here");
// try to process the IPN POST
try {
$listener->requirePostMethod();
$verified = $listener->processIpn();
} catch (Exception $e) {
error_log($e->getMessage());
exit(0);
}
error_log("here2");
// Process the IPN
if ($verified) {
error_log("here3");
$errmsg = ''; // stores errors from fraud checks
// Split the custom variable
$split_custom = explode("&", $_POST['custom']);
$custom_array = array();
for ($i = 0; $i<count($split_custom); $i++) {
$current_set = explode("=", $split_custom[$i]);
$custom_array[$current_set[0]] = $current_set[1];
}
error_log("here4");
if (!isset($custom_array['game'])) {
$custom_array['game'] = 0;
}
if (!isset($custom_array['player'])) {
$custom_array['player'] = 0;
}
error_log("here5");
if (!empty($errmsg)) {
// manually investigate errors from the fraud checking
$body = "IPN failed fraud checks: \n$errmsg\n\n";
$body .= $listener->getTextReport();
mail('jafawcett#gmail.com', 'IPN Fraud Warning', $body);
} else {
mail('jafawcett#gmail.com', 'Successful IPN', $listener->getTextReport());
}
error_log("donor_un: ".$custom_array['donor_un']);
process_donation($_POST['mc_gross'], $custom_array['player'], $custom_array['game'], $custom_array['donor_name'], $_POST['payer_email'], $custom_array['donor_un']);
} else {
// manually investigate the invalid IPN
mail('jafawcett#gmail.com', 'Invalid IPN', $listener->getTextReport());
}
}
For the ipn listener class I'm using the one created by Micah Carrick and available here:
https://github.com/Quixotix/PHP-PayPal-IPN
I asked my direct contact at PayPal about this and got the following response...
In regards to the IPN issue, we had an outage last night. It was fixed
at about 1-2am, the IPN’s are delayed because we had a backed up queue
of about 2.5 million IPN’s which did not send out. We are currently
working through these IPN’s. I’d expect normal functionality shortly.
You can also see plenty of people talking about this issue on Twitter.
We're having the same problem.
It worked perfectly fine for a few months now and the script remains untouched. PayPal IPN is enabled inside the PayPal account as well and our IPNs just stopped this morning.
There might be a problem over at PayPal, we're still trying to figure it out.