merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit af03e45182f4f450621ce98a6bd23bfaf2671c59
parent f8c673dd6ae62fe61ea0c6522c882b1ceb7b6e61
Author: Marcello Stanisci <marcello.stanisci@inria.fr>
Date:   Tue, 23 Feb 2016 17:12:18 +0100

addressing #4197, to test

Diffstat:
Rsrc/frontend_lib/config.php -> copylib/config.php | 0
Acopylib/merchants.php | 161+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rsrc/frontend/taler-presence.js -> copylib/taler-presence.js | 0
Rsrc/frontend_lib/util.php -> copylib/util.php | 0
Rsrc/frontend/README -> examples/frontend/README | 0
Rsrc/frontend/checkout.php -> examples/frontend/checkout.php | 0
Rsrc/frontend/config.php -> examples/frontend/config.php | 0
Aexamples/frontend/fulfillment.php | 119+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aexamples/frontend/generate_taler_contract.php | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aexamples/frontend/index.php | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aexamples/frontend/pay.php | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rsrc/frontend/style.css -> examples/frontend/style.css | 0
Rsrc/frontend/taler-presence.js -> examples/frontend/taler-presence.js | 0
Rsrc/frontend_blog/articles/arabic.jpg -> examples/frontend_blog/articles/arabic.jpg | 0
Rsrc/frontend_blog/articles/belarusian.jpg -> examples/frontend_blog/articles/belarusian.jpg | 0
Rsrc/frontend_blog/articles/bulgarian.jpg -> examples/frontend_blog/articles/bulgarian.jpg | 0
Rsrc/frontend_blog/articles/category.jpg -> examples/frontend_blog/articles/category.jpg | 0
Rsrc/frontend_blog/articles/chinese-simplified.jpg -> examples/frontend_blog/articles/chinese-simplified.jpg | 0
Rsrc/frontend_blog/articles/chinese-traditional.jpg -> examples/frontend_blog/articles/chinese-traditional.jpg | 0
Rsrc/frontend_blog/articles/code.jpg -> examples/frontend_blog/articles/code.jpg | 0
Rsrc/frontend_blog/articles/farsi.jpg -> examples/frontend_blog/articles/farsi.jpg | 0
Rsrc/frontend_blog/articles/greek.jpg -> examples/frontend_blog/articles/greek.jpg | 0
Rsrc/frontend_blog/articles/japanese-kana.jpg -> examples/frontend_blog/articles/japanese-kana.jpg | 0
Rsrc/frontend_blog/articles/japanese-kanji.jpg -> examples/frontend_blog/articles/japanese-kanji.jpg | 0
Rsrc/frontend_blog/articles/korean.jpg -> examples/frontend_blog/articles/korean.jpg | 0
Rsrc/frontend_blog/articles/russian.jpg -> examples/frontend_blog/articles/russian.jpg | 0
Rsrc/frontend_blog/articles/scrap1_1.html -> examples/frontend_blog/articles/scrap1_1.html | 0
Rsrc/frontend_blog/articles/scrap1_10.html -> examples/frontend_blog/articles/scrap1_10.html | 0
Rsrc/frontend_blog/articles/scrap1_11.html -> examples/frontend_blog/articles/scrap1_11.html | 0
Rsrc/frontend_blog/articles/scrap1_12.html -> examples/frontend_blog/articles/scrap1_12.html | 0
Rsrc/frontend_blog/articles/scrap1_13.html -> examples/frontend_blog/articles/scrap1_13.html | 0
Rsrc/frontend_blog/articles/scrap1_14.html -> examples/frontend_blog/articles/scrap1_14.html | 0
Rsrc/frontend_blog/articles/scrap1_15.html -> examples/frontend_blog/articles/scrap1_15.html | 0
Rsrc/frontend_blog/articles/scrap1_16.html -> examples/frontend_blog/articles/scrap1_16.html | 0
Rsrc/frontend_blog/articles/scrap1_17.html -> examples/frontend_blog/articles/scrap1_17.html | 0
Rsrc/frontend_blog/articles/scrap1_18.html -> examples/frontend_blog/articles/scrap1_18.html | 0
Rsrc/frontend_blog/articles/scrap1_19.html -> examples/frontend_blog/articles/scrap1_19.html | 0
Rsrc/frontend_blog/articles/scrap1_2.html -> examples/frontend_blog/articles/scrap1_2.html | 0
Rsrc/frontend_blog/articles/scrap1_20.html -> examples/frontend_blog/articles/scrap1_20.html | 0
Rsrc/frontend_blog/articles/scrap1_21.html -> examples/frontend_blog/articles/scrap1_21.html | 0
Rsrc/frontend_blog/articles/scrap1_22.html -> examples/frontend_blog/articles/scrap1_22.html | 0
Rsrc/frontend_blog/articles/scrap1_23.html -> examples/frontend_blog/articles/scrap1_23.html | 0
Rsrc/frontend_blog/articles/scrap1_24.html -> examples/frontend_blog/articles/scrap1_24.html | 0
Rsrc/frontend_blog/articles/scrap1_25.html -> examples/frontend_blog/articles/scrap1_25.html | 0
Rsrc/frontend_blog/articles/scrap1_26.html -> examples/frontend_blog/articles/scrap1_26.html | 0
Rsrc/frontend_blog/articles/scrap1_27.html -> examples/frontend_blog/articles/scrap1_27.html | 0
Rsrc/frontend_blog/articles/scrap1_28.html -> examples/frontend_blog/articles/scrap1_28.html | 0
Rsrc/frontend_blog/articles/scrap1_29.html -> examples/frontend_blog/articles/scrap1_29.html | 0
Rsrc/frontend_blog/articles/scrap1_3.html -> examples/frontend_blog/articles/scrap1_3.html | 0
Rsrc/frontend_blog/articles/scrap1_30.html -> examples/frontend_blog/articles/scrap1_30.html | 0
Rsrc/frontend_blog/articles/scrap1_31.html -> examples/frontend_blog/articles/scrap1_31.html | 0
Rsrc/frontend_blog/articles/scrap1_32.html -> examples/frontend_blog/articles/scrap1_32.html | 0
Rsrc/frontend_blog/articles/scrap1_33.html -> examples/frontend_blog/articles/scrap1_33.html | 0
Rsrc/frontend_blog/articles/scrap1_34.html -> examples/frontend_blog/articles/scrap1_34.html | 0
Rsrc/frontend_blog/articles/scrap1_35.html -> examples/frontend_blog/articles/scrap1_35.html | 0
Rsrc/frontend_blog/articles/scrap1_36.html -> examples/frontend_blog/articles/scrap1_36.html | 0
Rsrc/frontend_blog/articles/scrap1_37.html -> examples/frontend_blog/articles/scrap1_37.html | 0
Rsrc/frontend_blog/articles/scrap1_38.html -> examples/frontend_blog/articles/scrap1_38.html | 0
Rsrc/frontend_blog/articles/scrap1_39.html -> examples/frontend_blog/articles/scrap1_39.html | 0
Rsrc/frontend_blog/articles/scrap1_4.html -> examples/frontend_blog/articles/scrap1_4.html | 0
Rsrc/frontend_blog/articles/scrap1_40.html -> examples/frontend_blog/articles/scrap1_40.html | 0
Rsrc/frontend_blog/articles/scrap1_41.html -> examples/frontend_blog/articles/scrap1_41.html | 0
Rsrc/frontend_blog/articles/scrap1_42.html -> examples/frontend_blog/articles/scrap1_42.html | 0
Rsrc/frontend_blog/articles/scrap1_43.html -> examples/frontend_blog/articles/scrap1_43.html | 0
Rsrc/frontend_blog/articles/scrap1_46.html -> examples/frontend_blog/articles/scrap1_46.html | 0
Rsrc/frontend_blog/articles/scrap1_47.html -> examples/frontend_blog/articles/scrap1_47.html | 0
Rsrc/frontend_blog/articles/scrap1_5.html -> examples/frontend_blog/articles/scrap1_5.html | 0
Rsrc/frontend_blog/articles/scrap1_6.html -> examples/frontend_blog/articles/scrap1_6.html | 0
Rsrc/frontend_blog/articles/scrap1_7.html -> examples/frontend_blog/articles/scrap1_7.html | 0
Rsrc/frontend_blog/articles/scrap1_8.html -> examples/frontend_blog/articles/scrap1_8.html | 0
Rsrc/frontend_blog/articles/scrap1_9.html -> examples/frontend_blog/articles/scrap1_9.html | 0
Rsrc/frontend_blog/articles/scrap1_U.0.html -> examples/frontend_blog/articles/scrap1_U.0.html | 0
Rsrc/frontend_blog/articles/scrap1_U.1.html -> examples/frontend_blog/articles/scrap1_U.1.html | 0
Rsrc/frontend_blog/articles/serbian-croatian.jpg -> examples/frontend_blog/articles/serbian-croatian.jpg | 0
Rsrc/frontend_blog/articles/song-book-jutta-scrunch-crop.jpg -> examples/frontend_blog/articles/song-book-jutta-scrunch-crop.jpg | 0
Rsrc/frontend_blog/articles/tamil.jpg -> examples/frontend_blog/articles/tamil.jpg | 0
Rsrc/frontend_blog/articles/ukrainian.jpg -> examples/frontend_blog/articles/ukrainian.jpg | 0
Rsrc/frontend_blog/blog_lib.php -> examples/frontend_blog/blog_lib.php | 0
Rsrc/frontend_blog/essay_cc-form.html -> examples/frontend_blog/essay_cc-form.html | 0
Aexamples/frontend_blog/essay_cc-fulfillment.php | 18++++++++++++++++++
Aexamples/frontend_blog/essay_contract.php | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aexamples/frontend_blog/essay_fulfillment.php | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aexamples/frontend_blog/essay_pay.php | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rsrc/frontend_blog/gnu.svg -> examples/frontend_blog/gnu.svg | 0
Rsrc/frontend_blog/index.html -> examples/frontend_blog/index.html | 0
Rsrc/frontend_blog/style.css -> examples/frontend_blog/style.css | 0
Rsrc/frontend/taler-presence.js -> examples/frontend_blog/taler-presence.js | 0
Dsrc/frontend/fulfillment.php | 119-------------------------------------------------------------------------------
Dsrc/frontend/generate_taler_contract.php | 134-------------------------------------------------------------------------------
Dsrc/frontend/index.php | 156-------------------------------------------------------------------------------
Dsrc/frontend/pay.php | 91-------------------------------------------------------------------------------
Dsrc/frontend_blog/essay_cc-fulfillment.php | 18------------------
Dsrc/frontend_blog/essay_contract.php | 80-------------------------------------------------------------------------------
Dsrc/frontend_blog/essay_fulfillment.php | 91-------------------------------------------------------------------------------
Dsrc/frontend_blog/essay_pay.php | 65-----------------------------------------------------------------
Dsrc/frontend_lib/merchants.php | 162-------------------------------------------------------------------------------
96 files changed, 938 insertions(+), 916 deletions(-)

diff --git a/src/frontend_lib/config.php b/copylib/config.php diff --git a/copylib/merchants.php b/copylib/merchants.php @@ -0,0 +1,161 @@ +<?php + +/** + * Return a contract proposition to forward to the backend + * Note that `teatax` is an associative array representing a + * Taler-style amount (so it has the usual <amount,fration,currency> + * triple). Moreover, `teatax` should be a *list* of taxes + */ +function _generate_contract($args){ + $contract = array ('amount' => + array ('value' => $args['amount_value'], + 'fraction' => $args['amount_fraction'], + 'currency' => $args['currency']), + 'max_fee' => + array ('value' => 3, + 'fraction' => 01010, + 'currency' => $args['currency']), + 'transaction_id' => $args['transaction_id'], + 'products' => array ( + array ('description' => $args['description'], + 'quantity' => 1, + 'price' => + array ('value' => $args['amount_value'], + 'fraction' => $args['amount_fraction'], + 'currency' => $args['currency']), + 'product_id' => $args['product_id'], + 'taxes' => $args['taxes'], + 'delivery_date' => "Some Date Format", + 'delivery_location' => 'LNAME1')), + 'timestamp' => "/Date(" . $args['now']->getTimestamp() . ")/", + 'expiry' => + "/Date(" . $args['now']->add(new DateInterval('P2W'))->getTimestamp() . ")/", + 'refund_deadline' => + "/Date(" . $args['now']->add(new DateInterval($args['refund_delta']))->getTimestamp() . ")/", + 'repurchase_correlation_id' => $args['correlation_id'], + 'fulfillment_url' => $args['fulfillment_url'], + 'merchant' => + array ('address' => 'LNAME2', + 'name' => $args['merchant_name'], + 'jurisdiction' => 'LNAME3'), + 'locations' => + array ('LNAME1' => + array ('country' => 'Test Country', + 'city' => 'Test City', + 'state' => 'Test State', + 'region' => 'Test Region', + 'province' => 'Test Province', + 'ZIP code' => 4908, + 'street' => 'test street', + 'street number' => 20), + 'LNAME2' => + array ('country' => 'Test Country', + 'city' => 'Test City', + 'state' => 'Test State', + 'region' => 'Test Region', + 'province' => 'Test Province', + 'ZIP code' => 4908, + 'street' => 'test street', + 'street number' => 20), + 'LNAME3' => + array ('country' => 'Test Country', + 'city' => 'Test City', + 'state' => 'Test State', + 'region' => 'Test Region', + 'province' => 'Test Province', + 'ZIP code' => 4908))); + $json = json_encode (array ('contract' => $contract), JSON_PRETTY_PRINT); + return $json; +} + +/** + * Return a contract proposition to forward to the backend + * Note that `teatax` is an associative array representing a + * Taler-style amount (so it has the usual <amount,fration,currency> + * triple). Moreover, `teatax` should be a *list* of taxes + */ +function generate_contract($amount_value, + $amount_fraction, + $currency, + $transaction_id, + $desc, + $p_id, + $corr_id, + $taxes, + $now, + $fulfillment_url){ + include("../frontend_lib/config.php"); + $contract = array ('amount' => array ('value' => $amount_value, + 'fraction' => $amount_fraction, + 'currency' => $currency), + 'max_fee' => array ('value' => 3, + 'fraction' => 01010, + 'currency' => $currency), + 'transaction_id' => $transaction_id, + 'products' => array ( + array ('description' => $desc, + 'quantity' => 1, + 'price' => array ('value' => $amount_value, + 'fraction' => $amount_fraction, + 'currency' => $currency), + 'product_id' => $p_id, + 'taxes' => $taxes, + 'delivery_date' => "Some Date Format", + 'delivery_location' => 'LNAME1')), + 'timestamp' => "/Date(" . $now->getTimestamp() . ")/", + 'expiry' => "/Date(" . $now->add(new DateInterval('P2W'))->getTimestamp() . ")/", + 'refund_deadline' => "/Date(" . $now->add(new DateInterval($REFUND_DELTA))->getTimestamp() . ")/", + 'repurchase_correlation_id' => $corr_id, + 'fulfillment_url' => $fulfillment_url, + 'merchant' => array ('address' => 'LNAME2', + 'name' => 'Free Software Foundation (demo)', + 'jurisdiction' => 'LNAME3'), + + 'locations' => array ('LNAME1' => array ('country' => 'Test Country', + 'city' => 'Test City', + 'state' => 'Test State', + 'region' => 'Test Region', + 'province' => 'Test Province', + 'ZIP code' => 4908, + 'street' => 'test street', + 'street number' => 20), + 'LNAME2' => array ('country' => 'Test Country', + 'city' => 'Test City', + 'state' => 'Test State', + 'region' => 'Test Region', + 'province' => 'Test Province', + 'ZIP code' => 4908, + 'street' => 'test street', + 'street number' => 20), + 'LNAME3' => array ('country' => 'Test Country', + 'city' => 'Test City', + 'state' => 'Test State', + 'region' => 'Test Region', + 'province' => 'Test Province', + 'ZIP code' => 4908))); + $json = json_encode (array ('contract' => $contract), JSON_PRETTY_PRINT); + return $json; +} + + + +/** + * Feed `$json` to the backend and return the "(pecl) http response object" + * corresponding to the `$backend_relative_url` call + */ +function give_to_backend($backend_host, $backend_relative_url, $json){ + $url = (new http\URL("http://$backend_host")) + ->mod(array ("path" => $backend_relative_url), http\Url::JOIN_PATH); + + $req = new http\Client\Request("POST", + $url, + array ("Content-Type" => "application/json")); + + $req->getBody()->append($json); + + // Execute the HTTP request + $client = new http\Client; + $client->enqueue($req)->send(); + return $client->getResponse(); +} +?> diff --git a/src/frontend/taler-presence.js b/copylib/taler-presence.js diff --git a/src/frontend_lib/util.php b/copylib/util.php diff --git a/src/frontend/README b/examples/frontend/README diff --git a/src/frontend/checkout.php b/examples/frontend/checkout.php diff --git a/src/frontend/config.php b/examples/frontend/config.php diff --git a/examples/frontend/fulfillment.php b/examples/frontend/fulfillment.php @@ -0,0 +1,119 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <title>Taler's "Demo" Shop</title> + <link rel="stylesheet" type="text/css" href="style.css"> + <script type="application/javascript" src="taler-presence.js"></script> + <script type="application/javascript"> + function executePayment(H_contract, pay_url, offering_url) { + var detail = { + H_contract: H_contract, + pay_url: pay_url, + offering_url: offering_url + }; + var eve = new CustomEvent('taler-execute-payment', {detail: detail}); + document.dispatchEvent(eve); + } + </script> +</head> +<body> + + <header> + <div id="logo"> + <svg height="100" width="100"> + <circle cx="50" cy="50" r="40" stroke="darkcyan" stroke-width="6" fill="white" /> + <text x="19" y="82" font-family="Verdana" font-size="90" fill="darkcyan">S</text> + </svg> + </div> + + <h1>Toy Store - Product Page</h1> + </header> + + <aside class="sidebar" id="left"> + </aside> + + <section id="main"> + <article> +<?php +/* + This file is part of GNU TALER. + Copyright (C) 2014, 2015 GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2.1, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along with + TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> + */ + +include '../../copylib/util.php'; + +$hc = get($_GET["uuid"]); + +if (empty($hc)) +{ + http_response_code(400); + echo "<p>Bad request (UUID missing)</p>"; + return; +} + +session_start(); + +$payments = get($_SESSION['payments'], array()); +$my_payment = get($payments[$hc]); + +// This will keep the query parameters. +$pay_url = url_rel("pay.php"); + +$offering_url = url_rel("checkout.php", true); + +if (null === $my_payment) +{ + echo "<p>you do not have the session state for this contract: " . $hc . "</p>"; + echo "<p>Asking the wallet to re-execute it ... </p>"; + echo "<script>executePayment('$hc', '$pay_url', '$offering_url');</script>"; + return; +} + +if (true !== get($my_payment["is_payed"], false)) +{ + echo "<p>you have not payed for this contract: " . $hc . "</p>"; + echo "<p>Asking the wallet to re-execute it ... </p>"; + echo "<script>executePayment('$hc', '$pay_url');</script>"; + return; +} + +$receiver = $my_payment["receiver"]; + +$news = false; +switch ($receiver) +{ + case "Taler": + $news = "https://taler.net/news"; + break; + case "GNUnet": + $news = "https://gnunet.org/"; + break; + case "Tor": + $news = "https://www.torproject.org/press/press.html.en"; + break; +} + +$msg = "<p>Thanks for donating to " . $receiver . ".</p>"; +if ($news) +{ + $msg .= "<p>Check our latest <a href=\"" . $news . "\">news!</a></p>"; +} + +echo $msg; + +?> + </article> + </section> +</body> +</html> diff --git a/examples/frontend/generate_taler_contract.php b/examples/frontend/generate_taler_contract.php @@ -0,0 +1,153 @@ +<?php +/* + This file is part of GNU TALER. + Copyright (C) 2014-2016 GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2.1, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along with + TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> + */ + +include '../../copylib/util.php'; +include "../../copylib/config.php"; +include "../../copylib/merchants.php"; + +session_start(); + +if (!isset($_SESSION['receiver'])) +{ + http_response_code(400); + die(); +} + +$receiver = $_SESSION['receiver']; +$amount_value = intval($_SESSION['amount_value']); +$amount_fraction = intval($_SESSION['amount_fraction']); +$currency = $_SESSION['currency']; + +// generate a front-end transaction id. +// In production context, we might want to +// record this value somewhere together +// with the rest of the contract data. +$transaction_id = rand(0, 2<<40); + +// Human-readable description of this deal +$desc = "Donation to " . $receiver; + +// Take a timestamp +$now = new DateTime('now'); + +// Include all information so we can +// restore the contract without storing it +$fulfillment_url = url_rel("fulfillment.php") + . '?uuid=${H_contract}' + . '&receiver=' . urlencode($receiver) + . '&aval=' . urlencode($amount_value) + . '&afrac=' . urlencode($amount_fraction) + . '&acurr=' . urlencode($currency) + . '&tid=' . $transaction_id; + + + $contract = _generate_contract(array("amount_value" => $amount_value, + "amount_fraction" => $amount_fraction, + "currency" => $currency, + "refund_delta" => 'P3M', + "transaction_id" => $transaction_id, + "description" => $desc, + "product_id" => $p_id, + "correlation_id" => "", + "merchant_name" => "Kudos Inc.", + "taxes" => array(), + "now" => $now, + "fulfillment_url" => $fulfillment_url)); + + +// pack the JSON for the contract + +/* +$contract = array( + 'fulfillment_url' => $fulfillment_url, + 'amount' => array( + 'value' => $amount_value, + 'fraction' => $amount_fraction, + 'currency' => $currency + ), + 'max_fee' => array( + 'value' => 3, + 'fraction' => 01010, + 'currency' => $currency + ), + 'transaction_id' => $transaction_id, + 'products' => array( + array( + 'description' => $desc, + 'quantity' => 1, + 'price' => array ( + 'value' => $amount_value, + 'fraction' => $amount_fraction, + 'currency' => $currency + ), + 'product_id' => $p_id, + ) + ), + 'timestamp' => "/Date(" . $now->getTimestamp() . ")/", + 'expiry' => "/Date(" . $now->add(new DateInterval('P2W'))->getTimestamp() . ")/", + 'refund_deadline' => "/Date(" . $now->add(new DateInterval('P3M'))->getTimestamp() . ")/", + 'merchant' => array( + 'name' => 'Kudos Inc.' + ) +); +*/ + +$json = json_encode(array( + 'contract' => $contract +), JSON_PRETTY_PRINT); + +$url = url_join("http://".$_SERVER["HTTP_HOST"], "backend/contract"); + +$req = new http\Client\Request("POST", + $url, + array ("Content-Type" => "application/json")); + +$req->getBody()->append($contract); + +// Execute the HTTP request +$client = new http\Client; +$client->enqueue($req)->send(); + +// Fetch the response +$resp = $client->getResponse(); +$status_code = $resp->getResponseCode(); + +// Our response code is the same we got from the backend: +http_response_code($status_code); + +// Now generate our body +if ($status_code != 200) +{ + echo json_encode(array( + 'error' => "internal error", + 'hint' => "backend indicated error", + 'detail' => $resp->body->toString() + ), JSON_PRETTY_PRINT); +} +else +{ + $got_json = json_decode($resp->body->toString(), true); + $hc = $got_json["H_contract"]; + + $payments = &pull($_SESSION, "payments", array()); + $payments[$hc] = array( + 'receiver' => $receiver, + ); + + echo json_encode ($got_json, JSON_PRETTY_PRINT); +} +?> diff --git a/examples/frontend/index.php b/examples/frontend/index.php @@ -0,0 +1,156 @@ +<!DOCTYPE html> +<?php +require_once "../../copylib/config.php"; +?> +<html lang="en"> +<head> + <title>Taler Donation Demo</title> + <link rel="stylesheet" type="text/css" href="style.css"> + <script src="taler-presence.js" type="text/javascript"></script> +<script type="text/javascript"> +<?php +echo "\tvar shop_currency = '$MERCHANT_CURRENCY';\n"; +?> + + function addOption(value, label) { + var s = document.getElementById("taler-donation"); + var e = document.createElement("option"); + e.textContent = label ? label : ("".concat(value, " ", shop_currency)); + e.value = value; + s.appendChild(e); + } + + function init() { + var e = document.getElementById("currency-input"); + e.value = shop_currency; + addOption("0.1"); + addOption("1.0"); + addOption("6.0", "".concat(5, " ", shop_currency)); + addOption("10"); + } + + document.addEventListener("DOMContentLoaded", init); + +</script> +</head> + +<body> + <header> + <div id="logo"> + <svg height="100" width="100"> + <circle cx="50" cy="50" r="40" stroke="darkcyan" stroke-width="6" fill="white" /> + <text x="19" y="82" font-family="Verdana" font-size="90" fill="darkcyan">S</text> + </svg> + </div> + + <h1>Toy &quot;Store&quot; - Taler Demo</h1> + </header> + + <aside class="sidebar" id="left"> + </aside> + + <section id="main"> + <article> + <h1>Welcome to the Taler Donation Demo</h1> + + <p>This "toy" website provides you with the ability to + experience using the + <a href="https://www.taler.net/">GNU Taler</a> + payment system without using + valuable currency. Instead, for the demonstrator we + will be using a "toy" currency, KUDOS. However, please remember that + Taler is designed to work with ordinary currencies, such + as Dollars or Euros, not just toy currencies. + <br> + This page, <tt>shop.demo.taler.net</tt> models the behavior of a + typical Web shop supporting Taler. The other pages of the demo, + <tt>mint.demo.taler.net</tt> and + <tt>bank.demo.taler.net</tt>, correspond to a Taler mint + and bank with tight Taler integration respectively. + </p> + </article> + + <section> + + <article> + <h2>Step 1: Installing the Taler wallet</h2> + <p class="taler-installed-hide"> + First, you need to <a href="http://demo.taler.net/">install</a> + the Taler wallet browser extension. + </p> + <p class="taler-installed-show"> + Congratulations, you have installed the Taler wallet correctly. + You can now proceed with the next steps. + </p> + </article> + + <article class="taler-installed-show"> + <h2>Step 2: Withdraw coins <sup>(occasionally)</sup></h2> + + <p>The next step is to withdraw coins, after all you cannot + pay with an empty wallet. To be allowed to withdraw + coins from a mint, you first need to transfer currency to the mint + using the normal banking system, for example by using a + wire transfer. If the bank offers a tight integration with Taler, it + may also support this directly over the home banking online interface. + <br> + For the demonstration, we have created a "bank" that + allows you to "wire" funds (in KUDOS) to the mint simply by + filling in the desired amount into a form. Naturally, when + using a real bank with real money, you would have to authenticate + and authorize the transfer. + <br> + Note that you would not do this step for each purchase or each shop. + Payment with Taler is like paying + with cash: you withdraw currency at the bank (or an ATM) and then + pay at many merchants without having to authenticate each time. + <br> + So, unless you have already done so, please go ahead and withdraw + KUDOS at the + <a href="http://bank.demo.taler.net/" target="_blank">Demo bank</a> + (opens in a new tab).</p> + </article> + + <article class="taler-installed-show"> + <h2>Step 3: Shop! <sup>(as long as you have KUDOS left)</sup></h2> + + <p>Now it is time to spend your hard earned KUDOS. + Note that we cannot really tell if you got any yet, + as your Taler wallet balance is visible to you, but + of course is hidden entirely from the shop.</p> + <p>The form that follows corresponds to the shopping + cart of a real Web shop; however, we kept it + very simple for the demonstration.</p> + <p>So, please choose a project and the amount of KUDOS you + wish to donate:</p> + + <form name="tform" action="checkout.php" method="POST"> + <div class="participation" id="fake-shop"> + <br> + <input type="radio" name="donation_receiver" value="Taler" checked="true">GNU Taler</input> + <br> + <input type="radio" name="donation_receiver" value="Tor">Tor</input> + <br> + <input type="radio" name="donation_receiver" value="GNUnet">GNUnet</input> + <br> + <select id="taler-donation" name="donation_amount"> + <!-- options will be added dynamically --> + </select> + <input id="currency-input" type="hidden" name="donation_currency"/> + <input type="submit" name="keyName" value="Donate!"/> + <br> + <br> + </div> + </form> + <p>(*) To make it a bit more fun, the 5 KUDOS option + is deliberately implemented with a fault: the merchant will try to + make you donate 6 KUDOS instead of the 5 KUDOS you got to see. But do + not worry, you will be given the opportunity to review the + final offer from the merchant in a window secured + by the Taler extension. That way, you can spot the + error before committing to an incorrect contract.</p> + </article> + </section> + </section> +</body> +</html> diff --git a/examples/frontend/pay.php b/examples/frontend/pay.php @@ -0,0 +1,91 @@ +<?php +/* + This file is part of GNU TALER. + Copyright (C) 2014, 2015 GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2.1, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along with + TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> + +*/ + +include '../../copylib/util.php'; + +$hc = get($_GET["uuid"]); +if (empty($hc)) +{ + http_response_code(400); + echo json_encode(array( + "error" => "missing parameter", + "parameter" => "uuid" + )); + return; +} + +// TODO: check if contract body matches URL parameters, +// so we won't generate a response for the wrong receiver. +$receiver = get($_GET["receiver"]); +if (empty($receiver)) +{ + http_response_code(400); + echo json_encode(array( + "error" => "missing parameter", + "parameter" => "receiver" + )); + return; +} + +$post_body = file_get_contents('php://input'); +$deposit_permission = json_decode ($post_body, true); + +/* Craft the HTTP request, note that the backend + could be on an entirely different machine if + desired. */ + +// Backend is relative to the shop site. +$url = url_rel("backend/pay"); + +$req = new http\Client\Request("POST", + $url, + array("Content-Type" => "application/json")); +$req->getBody()->append (json_encode ($deposit_permission)); + +// Execute the HTTP request +$client = new http\Client; +$client->enqueue($req)->send(); + +// Fetch the response +$resp = $client->getResponse(); +$status_code = $resp->getResponseCode(); + +// Our response code is the same we got from the backend: +http_response_code($status_code); + +// Now generate our body +if ($status_code != 200) +{ + $json = json_encode( + array( + "error" => "backend error", + "status" => $status_code, + "detail" => $resp->body->toString())); + echo $json; + die(); +} + +session_start(); + +$payments = &pull($_SESSION, "payments", array()); +$payments[$hc] = array( + 'receiver' => $receiver, + 'is_payed' => true +); + +?> diff --git a/src/frontend/style.css b/examples/frontend/style.css diff --git a/src/frontend/taler-presence.js b/examples/frontend/taler-presence.js diff --git a/src/frontend_blog/articles/arabic.jpg b/examples/frontend_blog/articles/arabic.jpg Binary files differ. diff --git a/src/frontend_blog/articles/belarusian.jpg b/examples/frontend_blog/articles/belarusian.jpg Binary files differ. diff --git a/src/frontend_blog/articles/bulgarian.jpg b/examples/frontend_blog/articles/bulgarian.jpg Binary files differ. diff --git a/src/frontend_blog/articles/category.jpg b/examples/frontend_blog/articles/category.jpg Binary files differ. diff --git a/src/frontend_blog/articles/chinese-simplified.jpg b/examples/frontend_blog/articles/chinese-simplified.jpg Binary files differ. diff --git a/src/frontend_blog/articles/chinese-traditional.jpg b/examples/frontend_blog/articles/chinese-traditional.jpg Binary files differ. diff --git a/src/frontend_blog/articles/code.jpg b/examples/frontend_blog/articles/code.jpg Binary files differ. diff --git a/src/frontend_blog/articles/farsi.jpg b/examples/frontend_blog/articles/farsi.jpg Binary files differ. diff --git a/src/frontend_blog/articles/greek.jpg b/examples/frontend_blog/articles/greek.jpg Binary files differ. diff --git a/src/frontend_blog/articles/japanese-kana.jpg b/examples/frontend_blog/articles/japanese-kana.jpg Binary files differ. diff --git a/src/frontend_blog/articles/japanese-kanji.jpg b/examples/frontend_blog/articles/japanese-kanji.jpg Binary files differ. diff --git a/src/frontend_blog/articles/korean.jpg b/examples/frontend_blog/articles/korean.jpg Binary files differ. diff --git a/src/frontend_blog/articles/russian.jpg b/examples/frontend_blog/articles/russian.jpg Binary files differ. diff --git a/src/frontend_blog/articles/scrap1_1.html b/examples/frontend_blog/articles/scrap1_1.html diff --git a/src/frontend_blog/articles/scrap1_10.html b/examples/frontend_blog/articles/scrap1_10.html diff --git a/src/frontend_blog/articles/scrap1_11.html b/examples/frontend_blog/articles/scrap1_11.html diff --git a/src/frontend_blog/articles/scrap1_12.html b/examples/frontend_blog/articles/scrap1_12.html diff --git a/src/frontend_blog/articles/scrap1_13.html b/examples/frontend_blog/articles/scrap1_13.html diff --git a/src/frontend_blog/articles/scrap1_14.html b/examples/frontend_blog/articles/scrap1_14.html diff --git a/src/frontend_blog/articles/scrap1_15.html b/examples/frontend_blog/articles/scrap1_15.html diff --git a/src/frontend_blog/articles/scrap1_16.html b/examples/frontend_blog/articles/scrap1_16.html diff --git a/src/frontend_blog/articles/scrap1_17.html b/examples/frontend_blog/articles/scrap1_17.html diff --git a/src/frontend_blog/articles/scrap1_18.html b/examples/frontend_blog/articles/scrap1_18.html diff --git a/src/frontend_blog/articles/scrap1_19.html b/examples/frontend_blog/articles/scrap1_19.html diff --git a/src/frontend_blog/articles/scrap1_2.html b/examples/frontend_blog/articles/scrap1_2.html diff --git a/src/frontend_blog/articles/scrap1_20.html b/examples/frontend_blog/articles/scrap1_20.html diff --git a/src/frontend_blog/articles/scrap1_21.html b/examples/frontend_blog/articles/scrap1_21.html diff --git a/src/frontend_blog/articles/scrap1_22.html b/examples/frontend_blog/articles/scrap1_22.html diff --git a/src/frontend_blog/articles/scrap1_23.html b/examples/frontend_blog/articles/scrap1_23.html diff --git a/src/frontend_blog/articles/scrap1_24.html b/examples/frontend_blog/articles/scrap1_24.html diff --git a/src/frontend_blog/articles/scrap1_25.html b/examples/frontend_blog/articles/scrap1_25.html diff --git a/src/frontend_blog/articles/scrap1_26.html b/examples/frontend_blog/articles/scrap1_26.html diff --git a/src/frontend_blog/articles/scrap1_27.html b/examples/frontend_blog/articles/scrap1_27.html diff --git a/src/frontend_blog/articles/scrap1_28.html b/examples/frontend_blog/articles/scrap1_28.html diff --git a/src/frontend_blog/articles/scrap1_29.html b/examples/frontend_blog/articles/scrap1_29.html diff --git a/src/frontend_blog/articles/scrap1_3.html b/examples/frontend_blog/articles/scrap1_3.html diff --git a/src/frontend_blog/articles/scrap1_30.html b/examples/frontend_blog/articles/scrap1_30.html diff --git a/src/frontend_blog/articles/scrap1_31.html b/examples/frontend_blog/articles/scrap1_31.html diff --git a/src/frontend_blog/articles/scrap1_32.html b/examples/frontend_blog/articles/scrap1_32.html diff --git a/src/frontend_blog/articles/scrap1_33.html b/examples/frontend_blog/articles/scrap1_33.html diff --git a/src/frontend_blog/articles/scrap1_34.html b/examples/frontend_blog/articles/scrap1_34.html diff --git a/src/frontend_blog/articles/scrap1_35.html b/examples/frontend_blog/articles/scrap1_35.html diff --git a/src/frontend_blog/articles/scrap1_36.html b/examples/frontend_blog/articles/scrap1_36.html diff --git a/src/frontend_blog/articles/scrap1_37.html b/examples/frontend_blog/articles/scrap1_37.html diff --git a/src/frontend_blog/articles/scrap1_38.html b/examples/frontend_blog/articles/scrap1_38.html diff --git a/src/frontend_blog/articles/scrap1_39.html b/examples/frontend_blog/articles/scrap1_39.html diff --git a/src/frontend_blog/articles/scrap1_4.html b/examples/frontend_blog/articles/scrap1_4.html diff --git a/src/frontend_blog/articles/scrap1_40.html b/examples/frontend_blog/articles/scrap1_40.html diff --git a/src/frontend_blog/articles/scrap1_41.html b/examples/frontend_blog/articles/scrap1_41.html diff --git a/src/frontend_blog/articles/scrap1_42.html b/examples/frontend_blog/articles/scrap1_42.html diff --git a/src/frontend_blog/articles/scrap1_43.html b/examples/frontend_blog/articles/scrap1_43.html diff --git a/src/frontend_blog/articles/scrap1_46.html b/examples/frontend_blog/articles/scrap1_46.html diff --git a/src/frontend_blog/articles/scrap1_47.html b/examples/frontend_blog/articles/scrap1_47.html diff --git a/src/frontend_blog/articles/scrap1_5.html b/examples/frontend_blog/articles/scrap1_5.html diff --git a/src/frontend_blog/articles/scrap1_6.html b/examples/frontend_blog/articles/scrap1_6.html diff --git a/src/frontend_blog/articles/scrap1_7.html b/examples/frontend_blog/articles/scrap1_7.html diff --git a/src/frontend_blog/articles/scrap1_8.html b/examples/frontend_blog/articles/scrap1_8.html diff --git a/src/frontend_blog/articles/scrap1_9.html b/examples/frontend_blog/articles/scrap1_9.html diff --git a/src/frontend_blog/articles/scrap1_U.0.html b/examples/frontend_blog/articles/scrap1_U.0.html diff --git a/src/frontend_blog/articles/scrap1_U.1.html b/examples/frontend_blog/articles/scrap1_U.1.html diff --git a/src/frontend_blog/articles/serbian-croatian.jpg b/examples/frontend_blog/articles/serbian-croatian.jpg Binary files differ. diff --git a/src/frontend_blog/articles/song-book-jutta-scrunch-crop.jpg b/examples/frontend_blog/articles/song-book-jutta-scrunch-crop.jpg Binary files differ. diff --git a/src/frontend_blog/articles/tamil.jpg b/examples/frontend_blog/articles/tamil.jpg Binary files differ. diff --git a/src/frontend_blog/articles/ukrainian.jpg b/examples/frontend_blog/articles/ukrainian.jpg Binary files differ. diff --git a/src/frontend_blog/blog_lib.php b/examples/frontend_blog/blog_lib.php diff --git a/src/frontend_blog/essay_cc-form.html b/examples/frontend_blog/essay_cc-form.html diff --git a/examples/frontend_blog/essay_cc-fulfillment.php b/examples/frontend_blog/essay_cc-fulfillment.php @@ -0,0 +1,18 @@ +<?php + include '../../copylib/util.php'; + include './blog_lib.php'; + + $article = get($_GET['article']); + if (null == $article){ + http_response_code(400); + echo "Bad request (no article specified)"; + return; + } + + session_start(); + $payments = &pull($_SESSION, "payments", array()); + $payments[$article] = array("ispayed" => true); + $fulfillment_url = url_rel("essay_fulfillment.php"); + header("Location: $fulfillment_url"); + die(); +?> diff --git a/examples/frontend_blog/essay_contract.php b/examples/frontend_blog/essay_contract.php @@ -0,0 +1,82 @@ +<?php +/* + This file is part of GNU TALER. + Copyright (C) 2014, 2015 GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2.1, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along with + TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> +*/ + + include("../../copylib/merchants.php"); + include("../../copylib/util.php"); + include("../../copylib/config.php"); + include("./blog_lib.php"); + $article = get($_GET['article']); + if (null == $article){ + echo message_from_missing_param("article", "/"); + die(); + } + // send contract + $transaction_id = rand(0, 1001); + $now = new DateTime('now'); + $teaser = get_title($article); + $amount_value = 0; + $amount_fraction = 50000; + $teatax = array (); + $transaction_id = rand(0, 1001); + $fulfillment_url = url_rel("essay_fulfillment.php") + . '&timestamp=' . $now->getTimestamp() + . '&tid=' . $transaction_id; + +/* $contract_json = generate_contract($amount_value, + $amount_fraction, + $MERCHANT_CURRENCY, + $transaction_id, + trim($teaser), + $article, + $article, + $teatax, + $now, + $fulfillment_url);*/ + + $contract_json = _generate_contract(array("amount_value" => $amount_value, + "amount_fraction" => $amount_fraction, + "currency" => $MERCHANT_CURRENCY, + "refund_delta" => $REFUND_DELTA, + "transaction_id" => $transaction_id, + "description" => trim($teaser), + "merchant_name" => "Free Software Foundation (demo)", + "product_id" => $article, + "correlation_id" => $article, + "taxes" => $teatax, + "now" => $now, + "fulfillment_url" => $fulfillment_url)); + $resp = give_to_backend($_SERVER['HTTP_HOST'], + "backend/contract", + $contract_json); + $status_code = $resp->getResponseCode(); + http_response_code ($status_code); + if ($status_code != 200){ + echo json_encode(array( + 'error' => "internal error", + 'hint' => "backend indicated error", + 'detail' => $resp->body->toString() + ), JSON_PRETTY_PRINT); + } + else { + $got_json = json_decode($resp->body->toString(), true); + $hc = $got_json["H_contract"]; + session_start(); + $payments = &pull($_SESSION, "payments", array()); + $payments[$article] = array("ispayed" => false); + echo $resp->body->toString(); + } +?> diff --git a/examples/frontend_blog/essay_fulfillment.php b/examples/frontend_blog/essay_fulfillment.php @@ -0,0 +1,93 @@ +<?php +/* + This file is part of GNU TALER. + Copyright (C) 2014, 2015 GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2.1, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along with + TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> +*/ + include '../../copylib/util.php'; + include '../../copylib/merchants.php'; + include '../../copylib/config.php'; + include './blog_lib.php'; + + $article = get($_GET['article']); + if (null == $article){ + http_response_code(400); + echo message_from_missing_param("article", "/"); + return; + } + session_start(); + $payments = &pull($_SESSION, 'payments', array()); + $my_payment = &pull($payments, $article, array()); + $pay_url = url_rel("essay_pay.php"); + $offering_url = url_rel("essay_fulfillment.php", true); + $offering_url .= "?article=$article"; + //FIXME ispayed not always defined; wrap around some check + if (null === get($payments[$article]['ispayed']) || null === $my_payment){ + $tid = get($_GET['tid']); + $timestamp = get($_GET['timestamp']); + // 1st time + if (null == $tid || null == $timestamp){ + $js_code = "get_contract(\"$article\")"; + $cc_page = template("./essay_cc-form.html", array('article' => $article, 'jscode' => $js_code)); + echo $cc_page; + die(); + } + // restore contract + $now = new DateTime(); + $now->setTimestamp(intval($timestamp)); + + $contract_rec = _generate_contract(array("amount_value" => 0, + "amount_fraction" => 50000, + "currency" => $MERCHANT_CURRENCY, + "refund_delta" => $REFUND_DELTA, + "merchant_name" => "Free Software Foundation (demo)", + "transaction_id" => intval($tid), + "description" => trim(get_title($article)), + "product_id" => $article, + "correlation_id" => $article, + "taxes" => array(), + "now" => $now, + "fulfillment_url" => get_full_uri())); + /* + $contract_rec = generate_contract(0, + 50000, + $MERCHANT_CURRENCY, + intval($tid), + trim(get_title($article)), + $article, + $article, + array(), + $now, + get_full_uri());*/ + $resp = give_to_backend($_SERVER['HTTP_HOST'], + "backend/contract", + $contract_rec); + if ($resp->getResponseCode() != 200){ + echo json_encode(array( + 'error' => "internal error", + 'hint' => "non hashable contract", + 'detail' => $resp->body->toString() + ), JSON_PRETTY_PRINT); + die(); + } + $hc = json_decode($resp->body->toString(), true)['H_contract']; + $my_payment['hc'] = $hc; + $js_code = "executePayment('$hc', '$pay_url', '$offering_url')"; + $cc_page = template("./essay_cc-form.html", array('article' => $article, 'jscode' => $js_code)); + echo $cc_page; + return; + } + // control here == article payed + $article = get_article($article); + echo $article; +?> diff --git a/examples/frontend_blog/essay_pay.php b/examples/frontend_blog/essay_pay.php @@ -0,0 +1,65 @@ +<?php +/* + This file is part of GNU TALER. + Copyright (C) 2014, 2015 GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2.1, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along with + TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> +*/ + + include("../../copylib/merchants.php"); + include("../../copylib/util.php"); + include("./blog_lib.php"); + $article = get($_GET["article"]); + if (empty($article)){ + http_response_code(400); + echo json_encode(array( + "error" => "missing parameter", + "parameter" => "article" + )); + return; + } + $deposit_permission = file_get_contents('php://input'); + // FIXME check here if the deposit permission is associated + session_start(); + $payments = &pull($_SESSION, "payments", array()); + $dec_dep_perm = json_decode($deposit_permission, true); + if ($dec_dep_perm['H_contract'] != $payments[$article]['hc']){ + $json = json_encode( + array( + "error" => "ill behaved wallet", + "status" => 400, + "detail" => "article payed differs from article to be shown" + ) + ); + echo $json; + die(); + } + // FIXME put some control below + + // with the article that's going to be payed + $resp = give_to_backend($_SERVER['HTTP_HOST'], + "backend/pay", + $deposit_permission); + $status_code = $resp->getResponseCode(); + http_response_code ($status_code); + if ($status_code != 200) + { + $json = json_encode( + array( + "error" => "backend error", + "status" => $status_code, + "detail" => $resp->body->toString())); + echo $json; + die(); + } + $payments[$article]['ispayed'] = true; +?> diff --git a/src/frontend_blog/gnu.svg b/examples/frontend_blog/gnu.svg diff --git a/src/frontend_blog/index.html b/examples/frontend_blog/index.html diff --git a/src/frontend_blog/style.css b/examples/frontend_blog/style.css diff --git a/src/frontend/taler-presence.js b/examples/frontend_blog/taler-presence.js diff --git a/src/frontend/fulfillment.php b/src/frontend/fulfillment.php @@ -1,119 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -<head> - <title>Taler's "Demo" Shop</title> - <link rel="stylesheet" type="text/css" href="style.css"> - <script type="application/javascript" src="taler-presence.js"></script> - <script type="application/javascript"> - function executePayment(H_contract, pay_url, offering_url) { - var detail = { - H_contract: H_contract, - pay_url: pay_url, - offering_url: offering_url - }; - var eve = new CustomEvent('taler-execute-payment', {detail: detail}); - document.dispatchEvent(eve); - } - </script> -</head> -<body> - - <header> - <div id="logo"> - <svg height="100" width="100"> - <circle cx="50" cy="50" r="40" stroke="darkcyan" stroke-width="6" fill="white" /> - <text x="19" y="82" font-family="Verdana" font-size="90" fill="darkcyan">S</text> - </svg> - </div> - - <h1>Toy Store - Product Page</h1> - </header> - - <aside class="sidebar" id="left"> - </aside> - - <section id="main"> - <article> -<?php -/* - This file is part of GNU TALER. - Copyright (C) 2014, 2015 GNUnet e.V. - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> - */ - -include '../frontend_lib/util.php'; - -$hc = get($_GET["uuid"]); - -if (empty($hc)) -{ - http_response_code(400); - echo "<p>Bad request (UUID missing)</p>"; - return; -} - -session_start(); - -$payments = get($_SESSION['payments'], array()); -$my_payment = get($payments[$hc]); - -// This will keep the query parameters. -$pay_url = url_rel("pay.php"); - -$offering_url = url_rel("checkout.php", true); - -if (null === $my_payment) -{ - echo "<p>you do not have the session state for this contract: " . $hc . "</p>"; - echo "<p>Asking the wallet to re-execute it ... </p>"; - echo "<script>executePayment('$hc', '$pay_url', '$offering_url');</script>"; - return; -} - -if (true !== get($my_payment["is_payed"], false)) -{ - echo "<p>you have not payed for this contract: " . $hc . "</p>"; - echo "<p>Asking the wallet to re-execute it ... </p>"; - echo "<script>executePayment('$hc', '$pay_url');</script>"; - return; -} - -$receiver = $my_payment["receiver"]; - -$news = false; -switch ($receiver) -{ - case "Taler": - $news = "https://taler.net/news"; - break; - case "GNUnet": - $news = "https://gnunet.org/"; - break; - case "Tor": - $news = "https://www.torproject.org/press/press.html.en"; - break; -} - -$msg = "<p>Thanks for donating to " . $receiver . ".</p>"; -if ($news) -{ - $msg .= "<p>Check our latest <a href=\"" . $news . "\">news!</a></p>"; -} - -echo $msg; - -?> - </article> - </section> -</body> -</html> diff --git a/src/frontend/generate_taler_contract.php b/src/frontend/generate_taler_contract.php @@ -1,134 +0,0 @@ -<?php -/* - This file is part of GNU TALER. - Copyright (C) 2014-2016 GNUnet e.V. - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> - */ - -include '../frontend_lib/util.php'; -include "../frontend_lib/config.php"; - -session_start(); - -if (!isset($_SESSION['receiver'])) -{ - http_response_code(400); - die(); -} - -$receiver = $_SESSION['receiver']; -$amount_value = intval($_SESSION['amount_value']); -$amount_fraction = intval($_SESSION['amount_fraction']); -$currency = $_SESSION['currency']; - -// generate a front-end transaction id. -// In production context, we might want to -// record this value somewhere together -// with the rest of the contract data. -$transaction_id = rand(0, 2<<40); - -// Human-readable description of this deal -$desc = "Donation to " . $receiver; - -// Take a timestamp -$now = new DateTime('now'); - -// Include all information so we can -// restore the contract without storing it -$fulfillment_url = url_rel("fulfillment.php") - . '?uuid=${H_contract}' - . '&receiver=' . urlencode($receiver) - . '&aval=' . urlencode($amount_value) - . '&afrac=' . urlencode($amount_fraction) - . '&acurr=' . urlencode($currency) - . '&tid=' . $transaction_id; - -// pack the JSON for the contract -$contract = array( - 'fulfillment_url' => $fulfillment_url, - 'amount' => array( - 'value' => $amount_value, - 'fraction' => $amount_fraction, - 'currency' => $currency - ), - 'max_fee' => array( - 'value' => 3, - 'fraction' => 01010, - 'currency' => $currency - ), - 'transaction_id' => $transaction_id, - 'products' => array( - array( - 'description' => $desc, - 'quantity' => 1, - 'price' => array ( - 'value' => $amount_value, - 'fraction' => $amount_fraction, - 'currency' => $currency - ), - 'product_id' => $p_id, - ) - ), - 'timestamp' => "/Date(" . $now->getTimestamp() . ")/", - 'expiry' => "/Date(" . $now->add(new DateInterval('P2W'))->getTimestamp() . ")/", - 'refund_deadline' => "/Date(" . $now->add(new DateInterval('P3M'))->getTimestamp() . ")/", - 'merchant' => array( - 'name' => 'Kudos Inc.' - ) -); - -$json = json_encode(array( - 'contract' => $contract -), JSON_PRETTY_PRINT); - -$url = url_join("http://".$_SERVER["HTTP_HOST"], "backend/contract"); - -$req = new http\Client\Request("POST", - $url, - array ("Content-Type" => "application/json")); - -$req->getBody()->append($json); - -// Execute the HTTP request -$client = new http\Client; -$client->enqueue($req)->send(); - -// Fetch the response -$resp = $client->getResponse(); -$status_code = $resp->getResponseCode(); - -// Our response code is the same we got from the backend: -http_response_code($status_code); - -// Now generate our body -if ($status_code != 200) -{ - echo json_encode(array( - 'error' => "internal error", - 'hint' => "backend indicated error", - 'detail' => $resp->body->toString() - ), JSON_PRETTY_PRINT); -} -else -{ - $got_json = json_decode($resp->body->toString(), true); - $hc = $got_json["H_contract"]; - - $payments = &pull($_SESSION, "payments", array()); - $payments[$hc] = array( - 'receiver' => $receiver, - ); - - echo json_encode ($got_json, JSON_PRETTY_PRINT); -} -?> diff --git a/src/frontend/index.php b/src/frontend/index.php @@ -1,156 +0,0 @@ -<!DOCTYPE html> -<?php -require_once "../frontend_lib/config.php"; -?> -<html lang="en"> -<head> - <title>Taler Donation Demo</title> - <link rel="stylesheet" type="text/css" href="style.css"> - <script src="taler-presence.js" type="text/javascript"></script> -<script type="text/javascript"> -<?php -echo "\tvar shop_currency = '$MERCHANT_CURRENCY';\n"; -?> - - function addOption(value, label) { - var s = document.getElementById("taler-donation"); - var e = document.createElement("option"); - e.textContent = label ? label : ("".concat(value, " ", shop_currency)); - e.value = value; - s.appendChild(e); - } - - function init() { - var e = document.getElementById("currency-input"); - e.value = shop_currency; - addOption("0.1"); - addOption("1.0"); - addOption("6.0", "".concat(5, " ", shop_currency)); - addOption("10"); - } - - document.addEventListener("DOMContentLoaded", init); - -</script> -</head> - -<body> - <header> - <div id="logo"> - <svg height="100" width="100"> - <circle cx="50" cy="50" r="40" stroke="darkcyan" stroke-width="6" fill="white" /> - <text x="19" y="82" font-family="Verdana" font-size="90" fill="darkcyan">S</text> - </svg> - </div> - - <h1>Toy &quot;Store&quot; - Taler Demo</h1> - </header> - - <aside class="sidebar" id="left"> - </aside> - - <section id="main"> - <article> - <h1>Welcome to the Taler Donation Demo</h1> - - <p>This "toy" website provides you with the ability to - experience using the - <a href="https://www.taler.net/">GNU Taler</a> - payment system without using - valuable currency. Instead, for the demonstrator we - will be using a "toy" currency, KUDOS. However, please remember that - Taler is designed to work with ordinary currencies, such - as Dollars or Euros, not just toy currencies. - <br> - This page, <tt>shop.demo.taler.net</tt> models the behavior of a - typical Web shop supporting Taler. The other pages of the demo, - <tt>mint.demo.taler.net</tt> and - <tt>bank.demo.taler.net</tt>, correspond to a Taler mint - and bank with tight Taler integration respectively. - </p> - </article> - - <section> - - <article> - <h2>Step 1: Installing the Taler wallet</h2> - <p class="taler-installed-hide"> - First, you need to <a href="http://demo.taler.net/">install</a> - the Taler wallet browser extension. - </p> - <p class="taler-installed-show"> - Congratulations, you have installed the Taler wallet correctly. - You can now proceed with the next steps. - </p> - </article> - - <article class="taler-installed-show"> - <h2>Step 2: Withdraw coins <sup>(occasionally)</sup></h2> - - <p>The next step is to withdraw coins, after all you cannot - pay with an empty wallet. To be allowed to withdraw - coins from a mint, you first need to transfer currency to the mint - using the normal banking system, for example by using a - wire transfer. If the bank offers a tight integration with Taler, it - may also support this directly over the home banking online interface. - <br> - For the demonstration, we have created a "bank" that - allows you to "wire" funds (in KUDOS) to the mint simply by - filling in the desired amount into a form. Naturally, when - using a real bank with real money, you would have to authenticate - and authorize the transfer. - <br> - Note that you would not do this step for each purchase or each shop. - Payment with Taler is like paying - with cash: you withdraw currency at the bank (or an ATM) and then - pay at many merchants without having to authenticate each time. - <br> - So, unless you have already done so, please go ahead and withdraw - KUDOS at the - <a href="http://bank.demo.taler.net/" target="_blank">Demo bank</a> - (opens in a new tab).</p> - </article> - - <article class="taler-installed-show"> - <h2>Step 3: Shop! <sup>(as long as you have KUDOS left)</sup></h2> - - <p>Now it is time to spend your hard earned KUDOS. - Note that we cannot really tell if you got any yet, - as your Taler wallet balance is visible to you, but - of course is hidden entirely from the shop.</p> - <p>The form that follows corresponds to the shopping - cart of a real Web shop; however, we kept it - very simple for the demonstration.</p> - <p>So, please choose a project and the amount of KUDOS you - wish to donate:</p> - - <form name="tform" action="checkout.php" method="POST"> - <div class="participation" id="fake-shop"> - <br> - <input type="radio" name="donation_receiver" value="Taler" checked="true">GNU Taler</input> - <br> - <input type="radio" name="donation_receiver" value="Tor">Tor</input> - <br> - <input type="radio" name="donation_receiver" value="GNUnet">GNUnet</input> - <br> - <select id="taler-donation" name="donation_amount"> - <!-- options will be added dynamically --> - </select> - <input id="currency-input" type="hidden" name="donation_currency"/> - <input type="submit" name="keyName" value="Donate!"/> - <br> - <br> - </div> - </form> - <p>(*) To make it a bit more fun, the 5 KUDOS option - is deliberately implemented with a fault: the merchant will try to - make you donate 6 KUDOS instead of the 5 KUDOS you got to see. But do - not worry, you will be given the opportunity to review the - final offer from the merchant in a window secured - by the Taler extension. That way, you can spot the - error before committing to an incorrect contract.</p> - </article> - </section> - </section> -</body> -</html> diff --git a/src/frontend/pay.php b/src/frontend/pay.php @@ -1,91 +0,0 @@ -<?php -/* - This file is part of GNU TALER. - Copyright (C) 2014, 2015 GNUnet e.V. - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> - -*/ - -include '../frontend_lib/util.php'; - -$hc = get($_GET["uuid"]); -if (empty($hc)) -{ - http_response_code(400); - echo json_encode(array( - "error" => "missing parameter", - "parameter" => "uuid" - )); - return; -} - -// TODO: check if contract body matches URL parameters, -// so we won't generate a response for the wrong receiver. -$receiver = get($_GET["receiver"]); -if (empty($receiver)) -{ - http_response_code(400); - echo json_encode(array( - "error" => "missing parameter", - "parameter" => "receiver" - )); - return; -} - -$post_body = file_get_contents('php://input'); -$deposit_permission = json_decode ($post_body, true); - -/* Craft the HTTP request, note that the backend - could be on an entirely different machine if - desired. */ - -// Backend is relative to the shop site. -$url = url_rel("backend/pay"); - -$req = new http\Client\Request("POST", - $url, - array("Content-Type" => "application/json")); -$req->getBody()->append (json_encode ($deposit_permission)); - -// Execute the HTTP request -$client = new http\Client; -$client->enqueue($req)->send(); - -// Fetch the response -$resp = $client->getResponse(); -$status_code = $resp->getResponseCode(); - -// Our response code is the same we got from the backend: -http_response_code($status_code); - -// Now generate our body -if ($status_code != 200) -{ - $json = json_encode( - array( - "error" => "backend error", - "status" => $status_code, - "detail" => $resp->body->toString())); - echo $json; - die(); -} - -session_start(); - -$payments = &pull($_SESSION, "payments", array()); -$payments[$hc] = array( - 'receiver' => $receiver, - 'is_payed' => true -); - -?> diff --git a/src/frontend_blog/essay_cc-fulfillment.php b/src/frontend_blog/essay_cc-fulfillment.php @@ -1,18 +0,0 @@ -<?php - include '../frontend_lib/util.php'; - include './blog_lib.php'; - - $article = get($_GET['article']); - if (null == $article){ - http_response_code(400); - echo "Bad request (no article specified)"; - return; - } - - session_start(); - $payments = &pull($_SESSION, "payments", array()); - $payments[$article] = array("ispayed" => true); - $fulfillment_url = url_rel("essay_fulfillment.php"); - header("Location: $fulfillment_url"); - die(); -?> diff --git a/src/frontend_blog/essay_contract.php b/src/frontend_blog/essay_contract.php @@ -1,80 +0,0 @@ -<?php -/* - This file is part of GNU TALER. - Copyright (C) 2014, 2015 GNUnet e.V. - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> -*/ - - include("../frontend_lib/merchants.php"); - include("../frontend_lib/util.php"); - include("../frontend_lib/config.php"); - include("./blog_lib.php"); - $article = get($_GET['article']); - if (null == $article){ - echo message_from_missing_param("article", "/"); - die(); - } - // send contract - $transaction_id = rand(0, 1001); - $now = new DateTime('now'); - $teaser = get_title($article); - $amount_value = 0; - $amount_fraction = 50000; - $teatax = array (); - $transaction_id = rand(0, 1001); - $fulfillment_url = url_rel("essay_fulfillment.php") - . '&timestamp=' . $now->getTimestamp() - . '&tid=' . $transaction_id; - -/* $contract_json = generate_contract($amount_value, - $amount_fraction, - $MERCHANT_CURRENCY, - $transaction_id, - trim($teaser), - $article, - $article, - $teatax, - $now, - $fulfillment_url);*/ - - $contract_json = _generate_contract(array("amount_value" => $amount_value, - "amount_fraction" => $amount_fraction, - "currency" => $MERCHANT_CURRENCY, - "transaction_id" => $transaction_id, - "description" => trim($teaser), - "product_id" => $article, - "correlation_id" => $article, - "taxes" => $teatax, - "now" => $now, - "fulfillment_url" => $fulfillment_url)); - $resp = give_to_backend($_SERVER['HTTP_HOST'], - "backend/contract", - $contract_json); - $status_code = $resp->getResponseCode(); - http_response_code ($status_code); - if ($status_code != 200){ - echo json_encode(array( - 'error' => "internal error", - 'hint' => "backend indicated error", - 'detail' => $resp->body->toString() - ), JSON_PRETTY_PRINT); - } - else { - $got_json = json_decode($resp->body->toString(), true); - $hc = $got_json["H_contract"]; - session_start(); - $payments = &pull($_SESSION, "payments", array()); - $payments[$article] = array("ispayed" => false); - echo $resp->body->toString(); - } -?> diff --git a/src/frontend_blog/essay_fulfillment.php b/src/frontend_blog/essay_fulfillment.php @@ -1,91 +0,0 @@ -<?php -/* - This file is part of GNU TALER. - Copyright (C) 2014, 2015 GNUnet e.V. - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> -*/ - include '../frontend_lib/util.php'; - include '../frontend_lib/merchants.php'; - include '../frontend_lib/config.php'; - include './blog_lib.php'; - - $article = get($_GET['article']); - if (null == $article){ - http_response_code(400); - echo message_from_missing_param("article", "/"); - return; - } - session_start(); - $payments = &pull($_SESSION, 'payments', array()); - $my_payment = &pull($payments, $article, array()); - $pay_url = url_rel("essay_pay.php"); - $offering_url = url_rel("essay_fulfillment.php", true); - $offering_url .= "?article=$article"; - //FIXME ispayed not always defined; wrap around some check - if (false == $payments[$article]['ispayed'] || null === $my_payment){ - $tid = get($_GET['tid']); - $timestamp = get($_GET['timestamp']); - // 1st time - if (null == $tid || null == $timestamp){ - $js_code = "get_contract(\"$article\")"; - $cc_page = template("./essay_cc-form.html", array('article' => $article, 'jscode' => $js_code)); - echo $cc_page; - die(); - } - // restore contract - $now = new DateTime(); - $now->setTimestamp(intval($timestamp)); - - $contract_rec = _generate_contract(array("amount_value" => 0, - "amount_fraction" => 50000, - "currency" => $MERCHANT_CURRENCY, - "transaction_id" => intval($tid), - "description" => trim(get_title($article)), - "product_id" => $article, - "correlation_id" => $article, - "taxes" => array(), - "now" => $now, - "fulfillment_url" => get_full_uri())); - /* - $contract_rec = generate_contract(0, - 50000, - $MERCHANT_CURRENCY, - intval($tid), - trim(get_title($article)), - $article, - $article, - array(), - $now, - get_full_uri());*/ - $resp = give_to_backend($_SERVER['HTTP_HOST'], - "backend/contract", - $contract_rec); - if ($resp->getResponseCode() != 200){ - echo json_encode(array( - 'error' => "internal error", - 'hint' => "non hashable contract", - 'detail' => $resp->body->toString() - ), JSON_PRETTY_PRINT); - die(); - } - $hc = json_decode($resp->body->toString(), true)['H_contract']; - $my_payment['hc'] = $hc; - $js_code = "executePayment('$hc', '$pay_url', '$offering_url')"; - $cc_page = template("./essay_cc-form.html", array('article' => $article, 'jscode' => $js_code)); - echo $cc_page; - return; - } - // control here == article payed - $article = get_article($article); - echo $article; -?> diff --git a/src/frontend_blog/essay_pay.php b/src/frontend_blog/essay_pay.php @@ -1,65 +0,0 @@ -<?php -/* - This file is part of GNU TALER. - Copyright (C) 2014, 2015 GNUnet e.V. - - TALER is free software; you can redistribute it and/or modify it under the - terms of the GNU Lesser General Public License as published by the Free Software - Foundation; either version 2.1, or (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along with - TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> -*/ - - include("../frontend_lib/merchants.php"); - include("../frontend_lib/util.php"); - include("./blog_lib.php"); - $article = get($_GET["article"]); - if (empty($article)){ - http_response_code(400); - echo json_encode(array( - "error" => "missing parameter", - "parameter" => "article" - )); - return; - } - $deposit_permission = file_get_contents('php://input'); - // FIXME check here if the deposit permission is associated - session_start(); - $payments = &pull($_SESSION, "payments", array()); - $dec_dep_perm = json_decode($deposit_permission, true); - if ($dec_dep_perm['H_contract'] != $payments[$article]['hc']){ - $json = json_encode( - array( - "error" => "ill behaved wallet", - "status" => 400, - "detail" => "article payed differs from article to be shown" - ) - ); - echo $json; - die(); - } - // FIXME put some control below - - // with the article that's going to be payed - $resp = give_to_backend($_SERVER['HTTP_HOST'], - "backend/pay", - $deposit_permission); - $status_code = $resp->getResponseCode(); - http_response_code ($status_code); - if ($status_code != 200) - { - $json = json_encode( - array( - "error" => "backend error", - "status" => $status_code, - "detail" => $resp->body->toString())); - echo $json; - die(); - } - $payments[$article]['ispayed'] = true; -?> diff --git a/src/frontend_lib/merchants.php b/src/frontend_lib/merchants.php @@ -1,162 +0,0 @@ -<?php - -/** - * Return a contract proposition to forward to the backend - * Note that `teatax` is an associative array representing a - * Taler-style amount (so it has the usual <amount,fration,currency> - * triple). Moreover, `teatax` should be a *list* of taxes - */ -function _generate_contract($args){ - include("../frontend_lib/config.php"); - $contract = array ('amount' => - array ('value' => $args['amount_value'], - 'fraction' => $args['amount_fraction'], - 'currency' => $args['currency']), - 'max_fee' => - array ('value' => 3, - 'fraction' => 01010, - 'currency' => $args['currency']), - 'transaction_id' => $args['transaction_id'], - 'products' => array ( - array ('description' => $args['description'], - 'quantity' => 1, - 'price' => - array ('value' => $args['amount_value'], - 'fraction' => $args['amount_fraction'], - 'currency' => $args['currency']), - 'product_id' => $args['product_id'], - 'taxes' => $args['taxes'], - 'delivery_date' => "Some Date Format", - 'delivery_location' => 'LNAME1')), - 'timestamp' => "/Date(" . $args['now']->getTimestamp() . ")/", - 'expiry' => - "/Date(" . $args['now']->add(new DateInterval('P2W'))->getTimestamp() . ")/", - 'refund_deadline' => - "/Date(" . $args['now']->add(new DateInterval($REFUND_DELTA))->getTimestamp() . ")/", - 'repurchase_correlation_id' => $args['correlation_id'], - 'fulfillment_url' => $args['fulfillment_url'], - 'merchant' => - array ('address' => 'LNAME2', - 'name' => 'Free Software Foundations (demo)', - 'jurisdiction' => 'LNAME3'), - 'locations' => - array ('LNAME1' => - array ('country' => 'Test Country', - 'city' => 'Test City', - 'state' => 'Test State', - 'region' => 'Test Region', - 'province' => 'Test Province', - 'ZIP code' => 4908, - 'street' => 'test street', - 'street number' => 20), - 'LNAME2' => - array ('country' => 'Test Country', - 'city' => 'Test City', - 'state' => 'Test State', - 'region' => 'Test Region', - 'province' => 'Test Province', - 'ZIP code' => 4908, - 'street' => 'test street', - 'street number' => 20), - 'LNAME3' => - array ('country' => 'Test Country', - 'city' => 'Test City', - 'state' => 'Test State', - 'region' => 'Test Region', - 'province' => 'Test Province', - 'ZIP code' => 4908))); - $json = json_encode (array ('contract' => $contract), JSON_PRETTY_PRINT); - return $json; -} - -/** - * Return a contract proposition to forward to the backend - * Note that `teatax` is an associative array representing a - * Taler-style amount (so it has the usual <amount,fration,currency> - * triple). Moreover, `teatax` should be a *list* of taxes - */ -function generate_contract($amount_value, - $amount_fraction, - $currency, - $transaction_id, - $desc, - $p_id, - $corr_id, - $taxes, - $now, - $fulfillment_url){ - include("../frontend_lib/config.php"); - $contract = array ('amount' => array ('value' => $amount_value, - 'fraction' => $amount_fraction, - 'currency' => $currency), - 'max_fee' => array ('value' => 3, - 'fraction' => 01010, - 'currency' => $currency), - 'transaction_id' => $transaction_id, - 'products' => array ( - array ('description' => $desc, - 'quantity' => 1, - 'price' => array ('value' => $amount_value, - 'fraction' => $amount_fraction, - 'currency' => $currency), - 'product_id' => $p_id, - 'taxes' => $taxes, - 'delivery_date' => "Some Date Format", - 'delivery_location' => 'LNAME1')), - 'timestamp' => "/Date(" . $now->getTimestamp() . ")/", - 'expiry' => "/Date(" . $now->add(new DateInterval('P2W'))->getTimestamp() . ")/", - 'refund_deadline' => "/Date(" . $now->add(new DateInterval($REFUND_DELTA))->getTimestamp() . ")/", - 'repurchase_correlation_id' => $corr_id, - 'fulfillment_url' => $fulfillment_url, - 'merchant' => array ('address' => 'LNAME2', - 'name' => 'Free Software Foundation (demo)', - 'jurisdiction' => 'LNAME3'), - - 'locations' => array ('LNAME1' => array ('country' => 'Test Country', - 'city' => 'Test City', - 'state' => 'Test State', - 'region' => 'Test Region', - 'province' => 'Test Province', - 'ZIP code' => 4908, - 'street' => 'test street', - 'street number' => 20), - 'LNAME2' => array ('country' => 'Test Country', - 'city' => 'Test City', - 'state' => 'Test State', - 'region' => 'Test Region', - 'province' => 'Test Province', - 'ZIP code' => 4908, - 'street' => 'test street', - 'street number' => 20), - 'LNAME3' => array ('country' => 'Test Country', - 'city' => 'Test City', - 'state' => 'Test State', - 'region' => 'Test Region', - 'province' => 'Test Province', - 'ZIP code' => 4908))); - $json = json_encode (array ('contract' => $contract), JSON_PRETTY_PRINT); - return $json; -} - - - -/** - * Feed `$json` to the backend and return the "(pecl) http response object" - * corresponding to the `$backend_relative_url` call - */ -function give_to_backend($backend_host, $backend_relative_url, $json){ - $url = (new http\URL("http://$backend_host")) - ->mod(array ("path" => $backend_relative_url), http\Url::JOIN_PATH); - - $req = new http\Client\Request("POST", - $url, - array ("Content-Type" => "application/json")); - - $req->getBody()->append($json); - - // Execute the HTTP request - $client = new http\Client; - $client->enqueue($req)->send(); - return $client->getResponse(); -} -?>