0

It's the first time I'm implementing payments on my site.

I'd like to create a variable or auto-send a form that would make a variable or $_POST variable that takes value TRUE or FALSE depending on payment status.

Below is my idea of doing it but inspecting the source code of site in develop mode we can still see "hidden" values in which I specified GET variables (id) that would make it senseless because of lack of the variable that wouldn't be able to be changed by the user, now we can easily access the page xxx? id and the whole code would run despite even not clicking the payment button. Have you got any ideas or schemes what's the way to solve my problem? Thanks. FORM:

<form action="paypal...." method="post">
   <input type="hidden" name="cmd" value="xxx">
   <input type="hidden" name="business" value="xxxxx">
   <input type="hidden" name="item_name" value="xxx">
   <input type="hidden" name="currency_code" value="PLN">
   <input type="hidden" name="amount" value="0.01">
   <input type="hidden" name="return" value="http://xxx/xxx?id=xxxxxx">
   <input type="hidden" name="item_name" value="<?=$x?>">
   <input type="image" src="xxx" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form>

THE PAGE "xxx" in "return" input

$y=$_GET['id'];
header("Location: mecz?id=$y");
$osoba=$_GET['osoba'];
$osoba1=$_SESSION['zalogowany'];
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT ... FROM ... WHERE id='$y'";
$result = $conn->query($sql);
$row = $result->fetch_assoc();
$dobana = $row['ban'];
$dobana.=$_SESSION['zalogowany']." ";



if($_POST['unsign'])
{
    $sql = "UPDATE ... SET $... ='',ban='$dobana' WHERE id='$y'";
}
else
{
    $sql = "UPDATE ... SET $... ='$osoba1' WHERE id='$y'";
}

if ($conn->query($sql) === TRUE) {
    echo "Dodano osobe!";
} else {
    echo "Error: " . $sql . "<br>" . $conn->error;
}
Preston PHX
  • 27,642
  • 4
  • 24
  • 44
  • Before you make a session variable or use paramters like ?id=true . Please use **prepared statements** see for more information https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php – nbk Mar 23 '20 at 23:20
  • you do a `header("location:...")` right at the top, which makes the rest of the code (mostly) obsolete. – Jeff Mar 23 '20 at 23:52
  • is there no guide for paypal custumers like you on how to implement their service? – Jeff Mar 23 '20 at 23:53
  • ive tried to find a guide but it doesnt include any code or solutions etc. excluding js and form code – Bartek Juśkiewicz Mar 23 '20 at 23:59
  • 1
    I quickly found some examples here https://paypal.github.io/PayPal-PHP-SDK/sample/ and here https://developer.paypal.com/docs/checkout/ - they're not trivial, true - that's just the way online payment is: not trivial. – Jeff Mar 24 '20 at 00:50
  • The v1 PayPal-PHP-SDK is old and deprecated in favor of the v2 Checkout-PHP-SDK. I've added an answer where I go into a bit more detail on that, and also mention IPN/webhooks as a (not recommended, but possible) alternative – Preston PHX Mar 24 '20 at 09:01

1 Answers1

1

@Jeff's comment references finding examples at http://paypal.github.io/PayPal-PHP-SDK/samples. However, the v1 PayPal-PHP-SDK is old and should not be used

Instead, use the v2 Checkout-PHP-SDK

These API-based solutions will give you an immediate synchronous success/failure payment status response when you attempt the capture, which is the best solution to your problem.

For the best user experience, combine the v2 SDK on the server side with this front-end pattern: https://developer.paypal.com/demo/checkout/#/pattern/server

An alternative solution involves keeping the HTML-only web 1.0 form in the question and adding an asynchronous IPN or webhook listener for payment status updates. This is a less robust solution (depends on a separate asynchronous notification service), and an inferior web 1.0 payment experience, but may be easier to implement.


Assuming you are setting up API payments with intent:CAPTURE and doing an immediate capture after payer approval, then -- once you get the above working for the happy path -- don't neglect to handle funding source failures , so that if the capture fails on the server when e.g. a payer's first card is declined, this is propagated back to the UI and they can just select a different one.

Preston PHX
  • 27,642
  • 4
  • 24
  • 44
  • I understood the purpose but then, how can I access those files to create the order? Creating an order button but how should it work? To which file should it redirect? – Bartek Juśkiewicz Mar 25 '20 at 20:19
  • this button from front-end pattern should redirect to createorder page right? – Bartek Juśkiewicz Mar 25 '20 at 20:20
  • Not a redirect, an XHR/fetch call to retrieve just the order ID. This solution uses no redirects, it's a modern in-context experience. – Preston PHX Mar 25 '20 at 20:30
  • The createOrder javascript in the browser calls e.g. `/createorder` on your server. That server endpoint of yours is PHP which calls the PayPal API to create the order, and returns the order ID to the javascript. – Preston PHX Mar 25 '20 at 20:32
  • Similarly the onApprove function calls e.g. `/capture/XXXXXXXXX` on your server. That server endpoint of yours does the capture, and returns the result to the javascript. – Preston PHX Mar 25 '20 at 20:33
  • If the javascript sees a success result, then it redirects or does whatever you want it to do. This is an advanced solution, but gives you full control over the process. If you want something simpler, you might try the client-side demo pattern that does not use server-side API calls: https://developer.paypal.com/demo/checkout/#/pattern/client – Preston PHX Mar 25 '20 at 20:35
  • @BartekJuśkiewicz why you did not accepted that answer to indicate your question closed ? – bruno Mar 29 '20 at 13:27