processor_declined response for paypal braintree transaction - php

I have used non business account to create sandbox accounts.
Transactions are created:-
$amount = $_POST["amount"];
$nonce = $_POST["payment_method_nonce"];
$result = $gateway->transaction()->sale([
'amount' => $amount,
'paymentMethodNonce' => $nonce,
'options' => [
'submitForSettlement' => true]
]);
The result which I got is :
Error processing transaction: code: 2081 text: PayPal pending payments
are not supported
I am not sure is this issue occurred due to the account problem or the issue due to integration.

Making some research this is a currency issue coming from your sandbox account. I provide you with the answer and putting the source link to investigate further as this was an open ticket.
It looks like your sandbox account is setup to block payments from PayPal accounts with different currencies than the one you're making the request with.
If this is the behavior you want, you will need to create a test customer account with the same currency that you're using with the setup of Drop-in.
If this is not the behavior you want, you can log into sandbox.paypal.com and go to Profile > My Selling Tools > Block Payments to adjust the setting or Profile > My Money > PayPal Balance section > More > Currencies to add the currency of the account you are trying to use.
Source : Paypal sandbox issue

This solved for me:
1) Paypal: in paypal sandbox account I recreated a new Business Account indicating the Country where effectively run application (in my case: IT).
2) Paypal: With the business account just generated, I created new Paypal Application and I get paypal client ID and Secret.
3) Braintree: I re-linked my Paypal Sandbox application indicating credentuals of new Paypal business account: email, Client ID and Client Secret of the application just generated.
4) Into My Application/integration: in my braintree SDK js code (v3) I setted the right currency (in my case EUR) in the paypal setup js code:
<script>
var form = document.querySelector('#checkout-form');
var client_token = "{{ $clientToken }}";
var price = $('#selected_service_price').val();
braintree.dropin.create({
authorization: client_token,
selector: '#bt-dropin',
paypal: {
flow: 'checkout',
amount: price,
currency: 'EUR'
}
}, function (createErr, instance) {
if (createErr) {
console.log('Create Error', createErr);
return;
}
form.addEventListener('submit', function (event) {
event.preventDefault();
instance.requestPaymentMethod(function (err, payload) {
if (err) {
console.log('Request Payment Method Error', err);
return;
}
// Add the nonce to the form and submit
document.querySelector('#nonce').value = payload.nonce;
form.submit();
});
});
});

Related

Pass payment method id to create charge

What is the issue about?
I am trying to pass payment method id and customer to create single charge in php: https://stripe.com/docs/api/charges/create
I have successfully retrieved the Payment Method id for Payment Methods For Single Charges
Here is the code i JQuery
cardButton.addEventListener('click', (e) => {
stripe.createPaymentMethod(
"card", cardElement, {
billing_details: {
name: cardHolderName.value
}
}
).then(function(result) {
//Payment Method id retrieved here...
});
});
I have stripe customer ID, I also have stripe Payment Method id.
This is not about subscription...
As per the docs, there is no payment method property. How will I pass this info?
The Charges API (https://stripe.com/docs/api/charges/create) does not support passing a PaymentMethod object — it's an older API(https://stripe.com/docs/payments/legacy-apis) and you would generally not use it in a new integration today.
Instead, you would use the PaymentMethod that you obtained with a PaymentIntent on the backend. For example:
https://stripe.com/docs/payments/accept-a-payment-synchronously
if data['payment_method_id']
# Create the PaymentIntent
intent = Stripe::PaymentIntent.create(
payment_method: data['payment_method_id'], # from frontend
amount: 1099,
currency: 'usd',
confirmation_method: 'manual',
confirm: true,
)
# check intent.status for next steps...

Saving card details to customer using Stripe Elements

I have a little store I'm setting up, and so far, it's relatively simple. You can either order the product one time, weekly, or monthly.
I have set up the corresponding products in the Stripe Dashboard.
If the client sends that they want a recurring order, it creates a Customer with their information.
But whenever I try and create a recurring order, I receive a This customer has no attached payment source or default payment method. thrown in.
I'm using Stripe Elements, and since the card data never goes to my server, I'm not sure how to go about adding a payment method to this Customer.
Create subscription:
\Stripe\Subscription::create([
'customer' => $customer_id,
'items' => [
[
'price' => 'price_id_2',
'quantity' => $qty_1,
'price' => 'price_id_2',
'quantity' => $qty_2,
],
],
]);
$.post to send data to the PHP file
$.post('./secret.php', data, null, "json")
.done(function(data) {
clientSecret = data.client_secret;
stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: card,
}
}).then(function(result) {
if (result.error) {
console.log(result.error.message);
} else {
if (result.paymentIntent.status === 'succeeded') {
console.log("Payment success.");
document.getElementById("processing").classList.add("hide");
document.getElementById("order-success").classList.remove("hide");
}
}
})
})
.fail(function(xhr, status, error) {
document.getElementById("processing").classList.add("hide");
document.getElementById("order-failure").classList.remove("hide");
});
My one-time order works fine, but I just can't understand how to do this. The Docs show "Saving Card Data" as a deprecated utility, so I'm not sure what to do.
It sounds like you likely want to save a card during the payment process: https://stripe.com/docs/payments/save-during-payment

Stripe Payments Linking my own database table to a customer ID on Stripe

I am hoping someone can help me here.
I am trying to process subcription payments through stripe I have code that redirects you to the checkout once a button is clicked:
<script>
var stripe = Stripe('pk_test_CJ3p2EuKzHOC0mQrx9AIDZ3R00TR4ysmyS');
document.getElementById("checkout-button").addEventListener('click', function () {
stripe.redirectToCheckout({
items: [{
// Define the product and plan in the Dashboard first, and use the plan
// ID in your client-side code.
plan: 'plan_Fd6dQD8JT0sl0C',
quantity: 1,
}],
successUrl: 'https://www.example.com/success',
cancelUrl: 'https://www.example.com/cancel'
});
});
</script>
I then have set up a webhook to do some processing once this has completed:
<?php
require_once('vendor/autoload.php');
Stripe\Stripe::setApiKey("TEST KEY");
// retrieve the request's body and parse it as JSON
$body = #file_get_contents('php://input');
$event_json = json_decode($body);
// for extra security, retrieve from the Stripe API
$event_id = $event_json->id;
$event = \Stripe\Event::retrieve($event_id);
// This will send receipts on succesful invoices
if ($event->type == 'invoice.payment_succeeded') {
include 'email_template_functions/email_function.php';
include 'email_template_functions/password_reset_email_templatetest.php';
sendemail('triggertraders.com','richard#triggertraders.com','Bluebanana1995',465,'richard#triggertraders.com', 'Richard','rglass5565#gmail.com','richard#triggertraders.com',
'Information','Reset Password Trigger Trader','This has worked!!','This is the body in plain text for non-HTML mail clients');
}
So this works fine and the payments are going through to stripe its the next step I am wondering about.
I have a entity table in my database that contains all of the 'client' data which has an entity_id. I am trying to figure out a way to link the stripe customer_id to my entity_id in my local database so I can update their account when a payment is made but I cant see how I can do this.
Is there some way I can send my own entity_id to stripe when a payment is set up so when I retrive that data from the webhook and can update my database correctly?
I found this https://stripe.com/docs/stripe-js/reference#stripe-redirect-to-checkout it makes reference to clientReferenceId which I can use to store the ID that i need.
<script>
var stripe = Stripe('pk_test_CJ3p2EuKzHOC0mQrx9AIDZ3R00TR4ysmyS');
document.getElementById("checkout-button").addEventListener('click', function () {
stripe.redirectToCheckout({
items: [{
// Define the product and plan in the Dashboard first, and use the plan
// ID in your client-side code.
plan: 'plan_Fd6dQD8JT0sl0C',
quantity: 1,
}],
clientReferenceId: '123',
successUrl: 'https://www.example.com/success',
cancelUrl: 'https://www.example.com/cancel'
});
});
</script>
I then can use this in my webhook - anybody know of any other ways to do this?

Using Stripe Checkout to Allow a Customer to Purchase a Product

I've yet to find an answer to what should be a very straightforward approach to using Stripe (in my opinion). Using Stripe Checkout, how can I allow a person to pay for a product that I already have created in my "Products" section of the dashboard? All documentation that I have found shows how to retrieve product data, etc., and that's great, but it doesn't actually explain how to allow the customer to purchase the product with Checkout. I'm using PHP, but would be more than happy to see any examples in any language to follow the trajectory.
If you are attempting to do this using checkout.js or stripe elements, it is not possible. You will need to handle this server side by:
First get a token that's a representation of the card the customer submitted using Stripe Elements
subscribe
Script:
$('.btn-save-sub').click(function () {
//if your customer has chosen a plan, for example
var plan = $("#plan_id").val();
var stripe = Stripe(//your public key here );
var elements = stripe.elements();
/**create and mount cc and cc exp elements**/
var card = elements.create('card'); //complete card element, can be customized
card.mount('#card-element');
card.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
}else{
displayError.textContent = '';
}
});
var form = document.getElementById('subscription_add_new_source');
stripe.createToken(card).then(function(result) {
if (result.error) {
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
}else{
//post result.token.id and plan_id to your server, this token represents the card you will be using
}
});
});
Now, server side you have a token and a plan_id (if you've decided to allow customer to select a plan). Now we will subscribe the customer to the plan using stripe's PHP Bindings
//you have posted a plan_id to be used, you will create a subscription for that plan id, create a card objecting using the token you have, and attach that card as a default source to the stripe customer
$stripe_customer= //retrieve it, if you don't have one, create it
Create customer via stripe API
Once you have your customer you will first create a card object and assign that as the default source:
//create new card
$new_card = $stripe_customer->sources->create(array('sources'=>$posted_token));
//assign newly created card as customer's default source
//subscriptions can only charge default sources
$stripe_customer->default_source = $new_card->id;
//finally, create a subscription with the plan_id
$subscription = \Stripe\Subscription::create(
array(
'customer' => $stripe_customer->id,
'items' => array(
array(
'plan' => $posted_plan_id,
)
),
'trial_end' =>$end // represents the first day a customer will be charged for this plan, pass a timestamp
)
);

PayPal - Get transaction details for recurring profile

On making the TransactionSearch request I receive the list of the transactions with the TRANSACTIONID field for the transactions, corresponding to the recurring payments, in the form e.g. "I-BRPN2RUD8W0G" (current is fake).
For the rest transactions - I get usual 17 single-byte alphanumeric string. That means, that for recurring payments PayPal returns ProfileID, but not TransactionID.
As a result when I request the GetTransactionDetails with this transaction id passed to PayPal I receive valid details for ordinary payments and ERROR with the message "The transaction id is not valid" for the case of recurring payments.
You will need to set IPN as suggested by Sanjiv. You can get the fields as per IPN Variables. In case of refund you will also need to use parent_txn_id
If you are new with this and finding tough, you can use IPN listener class and then integrate below code
$listener = new IpnListener();
try {
$verified = $listener->processIpn();
} catch (Exception $e) {
return Log::error($e->getMessage());
}
if ($verified) {
$data = $_POST;
$user_id = json_decode($data['custom'])->user_id;
$subscription = ($data['mc_gross_1'] == '10') ? 2 : 1;
$txn = array(
'txn_id' => $data['txn_id'],
'user_id' => $user_id,
'paypal_id' => $data['subscr_id'],
'subscription' => $subscription,
'expires' => date('Y-m-d H:i:s', strtotime('+1 Month')),
);
Payment::create($txn);
} else {
Log::error('Transaction not verified');
}
Save this file code in file let say, ipn.php and now assign web path for this file in your paypal account.
PS: make sure your IPN file is on publicly accessible URL. Do not use local or restricted server.
You have to set IPN in your Paypal merchant account (specially for recurring payments), Which sends you back a transaction details when a recurring payment happens, from there you can get $_POST['txn_id'] which is your TRANSACTIONID if $_POST['txn_type'] is recurring_payment. Save the details in your database and then you can call GetTransactionDetails method when you need transaction details. More

Categories