| Author | Dave Jarvis <email> |
|---|---|
| Date | 2026-01-17 23:03:02 GMT-0800 |
| Commit | 8648b58258f4b004161707e99ed20ff7323a86e6 |
| +<!DOCTYPE html> | ||
| +<html lang="en"> | ||
| +<head> | ||
| + <meta charset="utf-8"> | ||
| + <title>autónoma – shipping</title> | ||
| + <link rel="stylesheet" href="main.css"> | ||
| +</head> | ||
| +<body> | ||
| + <h1>autónoma – shipping</h1> | ||
| + <form action="payment.php" method="post"> | ||
| + <p> | ||
| + Provide the mailing address. If this is a gift, provide the recipient’s | ||
| + name in the <strong>Gifted to</strong> field. | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="name">Name:</label> | ||
| + <input type="text" id="name" name="name" maxlength="100" required | ||
| + autofocus="autofocus"> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="street1">Address line 1:</label> | ||
| + <input type="text" id="street1" name="street1" maxlength="100" required> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="street2">Address line 2 (optional):</label> | ||
| + <input type="text" id="street2" name="street2" maxlength="100"> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="city">City:</label> | ||
| + <input type="text" id="city" name="city" maxlength="50" required> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="state">Prov/State:</label> | ||
| + <input type="text" id="state" name="state" maxlength="50" required> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="postcode">Postal code:</label> | ||
| + <input type="text" id="postcode" name="postcode" maxlength="20" required> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="country">Country:</label> | ||
| + <select name="country" id="country" required> | ||
| + <option value="AU">Australia</option> | ||
| + <option value="CA">Canada</option> | ||
| + <option value="IE">Ireland</option> | ||
| + <option value="NZ">New Zealand</option> | ||
| + <option value="GB">United Kingdom</option> | ||
| + <option value="US">United States</option> | ||
| + <hr> | ||
| + <option value="AF">Afghanistan</option> | ||
| + <option value="AX">Åland Islands</option> | ||
| + <option value="AL">Albania</option> | ||
| + <option value="DZ">Algeria</option> | ||
| + <option value="AS">American Samoa</option> | ||
| + <option value="AD">Andorra</option> | ||
| + <option value="AO">Angola</option> | ||
| + <option value="AI">Anguilla</option> | ||
| + <option value="AQ">Antarctica</option> | ||
| + <option value="AG">Antigua and Barbuda</option> | ||
| + <option value="AR">Argentina</option> | ||
| + <option value="AM">Armenia</option> | ||
| + <option value="AW">Aruba</option> | ||
| + <option value="AT">Austria</option> | ||
| + <option value="AZ">Azerbaijan</option> | ||
| + <option value="BS">Bahamas</option> | ||
| + <option value="BH">Bahrain</option> | ||
| + <option value="BD">Bangladesh</option> | ||
| + <option value="BB">Barbados</option> | ||
| + <option value="BY">Belarus</option> | ||
| + <option value="BE">Belgium</option> | ||
| + <option value="BZ">Belize</option> | ||
| + <option value="BJ">Benin</option> | ||
| + <option value="BM">Bermuda</option> | ||
| + <option value="BT">Bhutan</option> | ||
| + <option value="BO">Bolivia</option> | ||
| + <option value="BA">Bosnia and Herzegovina</option> | ||
| + <option value="BW">Botswana</option> | ||
| + <option value="BR">Brazil</option> | ||
| + <option value="BN">Brunei Darussalam</option> | ||
| + <option value="BG">Bulgaria</option> | ||
| + <option value="BF">Burkina Faso</option> | ||
| + <option value="BI">Burundi</option> | ||
| + <option value="KH">Cambodia</option> | ||
| + <option value="CM">Cameroon</option> | ||
| + <option value="CV">Cape Verde</option> | ||
| + <option value="KY">Cayman Islands</option> | ||
| + <option value="CF">Central African Republic</option> | ||
| + <option value="TD">Chad</option> | ||
| + <option value="CL">Chile</option> | ||
| + <option value="CN">China</option> | ||
| + <option value="CO">Colombia</option> | ||
| + <option value="KM">Comoros</option> | ||
| + <option value="CG">Congo</option> | ||
| + <option value="CR">Costa Rica</option> | ||
| + <option value="CI">Côte d'Ivoire</option> | ||
| + <option value="HR">Croatia</option> | ||
| + <option value="CW">Curaçao</option> | ||
| + <option value="CY">Cyprus</option> | ||
| + <option value="CZ">Czech Republic</option> | ||
| + <option value="DK">Denmark</option> | ||
| + <option value="DJ">Djibouti</option> | ||
| + <option value="DM">Dominica</option> | ||
| + <option value="DO">Dominican Republic</option> | ||
| + <option value="EC">Ecuador</option> | ||
| + <option value="EG">Egypt</option> | ||
| + <option value="SV">El Salvador</option> | ||
| + <option value="GQ">Equatorial Guinea</option> | ||
| + <option value="ER">Eritrea</option> | ||
| + <option value="EE">Estonia</option> | ||
| + <option value="ET">Ethiopia</option> | ||
| + <option value="FJ">Fiji</option> | ||
| + <option value="FI">Finland</option> | ||
| + <option value="FR">France</option> | ||
| + <option value="GA">Gabon</option> | ||
| + <option value="GM">Gambia</option> | ||
| + <option value="GE">Georgia</option> | ||
| + <option value="DE">Germany</option> | ||
| + <option value="GH">Ghana</option> | ||
| + <option value="GR">Greece</option> | ||
| + <option value="GD">Grenada</option> | ||
| + <option value="GT">Guatemala</option> | ||
| + <option value="GN">Guinea</option> | ||
| + <option value="GW">Guinea-Bissau</option> | ||
| + <option value="GY">Guyana</option> | ||
| + <option value="HT">Haiti</option> | ||
| + <option value="HN">Honduras</option> | ||
| + <option value="HK">Hong Kong</option> | ||
| + <option value="HU">Hungary</option> | ||
| + <option value="IS">Iceland</option> | ||
| + <option value="IN">India</option> | ||
| + <option value="ID">Indonesia</option> | ||
| + <option value="IQ">Iraq</option> | ||
| + <option value="IL">Israel</option> | ||
| + <option value="IT">Italy</option> | ||
| + <option value="JM">Jamaica</option> | ||
| + <option value="JP">Japan</option> | ||
| + <option value="JO">Jordan</option> | ||
| + <option value="KZ">Kazakhstan</option> | ||
| + <option value="KE">Kenya</option> | ||
| + <option value="KI">Kiribati</option> | ||
| + <option value="KR">Korea, Republic of</option> | ||
| + <option value="KW">Kuwait</option> | ||
| + <option value="KG">Kyrgyzstan</option> | ||
| + <option value="LA">Lao People's Democratic Republic</option> | ||
| + <option value="LV">Latvia</option> | ||
| + <option value="LB">Lebanon</option> | ||
| + <option value="LS">Lesotho</option> | ||
| + <option value="LR">Liberia</option> | ||
| + <option value="LI">Liechtenstein</option> | ||
| + <option value="LT">Lithuania</option> | ||
| + <option value="LU">Luxembourg</option> | ||
| + <option value="MO">Macao</option> | ||
| + <option value="MG">Madagascar</option> | ||
| + <option value="MW">Malawi</option> | ||
| + <option value="MY">Malaysia</option> | ||
| + <option value="MV">Maldives</option> | ||
| + <option value="ML">Mali</option> | ||
| + <option value="MT">Malta</option> | ||
| + <option value="MH">Marshall Islands</option> | ||
| + <option value="MR">Mauritania</option> | ||
| + <option value="MU">Mauritius</option> | ||
| + <option value="MX">Mexico</option> | ||
| + <option value="FM">Micronesia</option> | ||
| + <option value="MD">Moldova</option> | ||
| + <option value="MC">Monaco</option> | ||
| + <option value="MN">Mongolia</option> | ||
| + <option value="ME">Montenegro</option> | ||
| + <option value="MS">Montserrat</option> | ||
| + <option value="MA">Morocco</option> | ||
| + <option value="MZ">Mozambique</option> | ||
| + <option value="MM">Myanmar</option> | ||
| + <option value="NA">Namibia</option> | ||
| + <option value="NR">Nauru</option> | ||
| + <option value="NP">Nepal</option> | ||
| + <option value="NL">Netherlands</option> | ||
| + <option value="NI">Nicaragua</option> | ||
| + <option value="NE">Niger</option> | ||
| + <option value="NG">Nigeria</option> | ||
| + <option value="NO">Norway</option> | ||
| + <option value="OM">Oman</option> | ||
| + <option value="PK">Pakistan</option> | ||
| + <option value="PW">Palau</option> | ||
| + <option value="PA">Panama</option> | ||
| + <option value="PG">Papua New Guinea</option> | ||
| + <option value="PY">Paraguay</option> | ||
| + <option value="PE">Peru</option> | ||
| + <option value="PH">Philippines</option> | ||
| + <option value="PL">Poland</option> | ||
| + <option value="PT">Portugal</option> | ||
| + <option value="QA">Qatar</option> | ||
| + <option value="RE">Réunion</option> | ||
| + <option value="RO">Romania</option> | ||
| + <option value="RW">Rwanda</option> | ||
| + <option value="KN">Saint Kitts and Nevis</option> | ||
| + <option value="LC">Saint Lucia</option> | ||
| + <option value="VC">Saint Vincent and the Grenadines</option> | ||
| + <option value="WS">Samoa</option> | ||
| + <option value="SM">San Marino</option> | ||
| + <option value="ST">São Tomé and Príncipe</option> | ||
| + <option value="SA">Saudi Arabia</option> | ||
| + <option value="SN">Senegal</option> | ||
| + <option value="RS">Serbia</option> | ||
| + <option value="SC">Seychelles</option> | ||
| + <option value="SL">Sierra Leone</option> | ||
| + <option value="SG">Singapore</option> | ||
| + <option value="SK">Slovakia</option> | ||
| + <option value="SI">Slovenia</option> | ||
| + <option value="SB">Solomon Islands</option> | ||
| + <option value="SO">Somalia</option> | ||
| + <option value="ZA">South Africa</option> | ||
| + <option value="ES">Spain</option> | ||
| + <option value="LK">Sri Lanka</option> | ||
| + <option value="SD">Sudan</option> | ||
| + <option value="SR">Suriname</option> | ||
| + <option value="SZ">Swaziland</option> | ||
| + <option value="SE">Sweden</option> | ||
| + <option value="CH">Switzerland</option> | ||
| + <option value="TW">Taiwan</option> | ||
| + <option value="TJ">Tajikistan</option> | ||
| + <option value="TZ">Tanzania</option> | ||
| + <option value="TH">Thailand</option> | ||
| + <option value="TG">Togo</option> | ||
| + <option value="TO">Tonga</option> | ||
| + <option value="TT">Trinidad and Tobago</option> | ||
| + <option value="TN">Tunisia</option> | ||
| + <option value="TR">Turkey</option> | ||
| + <option value="TM">Turkmenistan</option> | ||
| + <option value="TV">Tuvalu</option> | ||
| + <option value="UG">Uganda</option> | ||
| + <option value="UA">Ukraine</option> | ||
| + <option value="AE">United Arab Emirates</option> | ||
| + <option value="UY">Uruguay</option> | ||
| + <option value="UZ">Uzbekistan</option> | ||
| + <option value="VU">Vanuatu</option> | ||
| + <option value="VE">Venezuela</option> | ||
| + <option value="VN">Vietnam</option> | ||
| + <option value="YE">Yemen</option> | ||
| + <option value="ZM">Zambia</option> | ||
| + <option value="ZW">Zimbabwe</option> | ||
| + </select> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="phone">Phone:</label> | ||
| + <input type="tel" id="phone" name="phone" maxlength="20" required> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="email">Email:</label> | ||
| + <input type="email" id="email" name="email" maxlength="254" required> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <label for="gifted">Gifted to (optional):</label> | ||
| + <input type="text" id="gifted" name="gifted" maxlength="100"> | ||
| + </p> | ||
| + | ||
| + <p> | ||
| + <button type="submit">Proceed to payment</button> | ||
| + </p> | ||
| + </form> | ||
| +</body> | ||
| +</html> | ||
| + | ||
| +body { | ||
| + font-family: sans-serif; | ||
| + background-color: #f5f5f5; | ||
| + padding: 40px 20px; | ||
| + margin: 0; | ||
| + color: #333; | ||
| +} | ||
| + | ||
| +h1, h2 { | ||
| + max-width: 500px; | ||
| + margin: 0 auto 20px auto; | ||
| + text-align: center; | ||
| +} | ||
| + | ||
| +form { | ||
| + max-width: 500px; | ||
| + margin-left: auto; | ||
| + margin-right: auto; | ||
| + background: white; | ||
| + padding: 15px; | ||
| + border: 1px solid #ddd; | ||
| + border-radius: 8px; | ||
| + display: grid; | ||
| + grid-template-columns: 1fr 1fr; | ||
| + gap: 0 15px; | ||
| +} | ||
| + | ||
| +/* Payment page content styling */ | ||
| +body:not(:has(form)) > h2 { | ||
| + max-width: 500px; | ||
| + margin-left: auto; | ||
| + margin-right: auto; | ||
| + background: white; | ||
| + padding: 15px; | ||
| + border: 1px solid #ddd; | ||
| + border-radius: 8px; | ||
| + margin-bottom: 15px; | ||
| +} | ||
| + | ||
| +.payment-content { | ||
| + max-width: 500px; | ||
| + margin: 0 auto; | ||
| + background: white; | ||
| + padding: 15px; | ||
| + border: 1px solid #ddd; | ||
| + border-radius: 8px; | ||
| +} | ||
| + | ||
| +.payment-content h2:first-child { | ||
| + margin-top: 0; | ||
| +} | ||
| + | ||
| +.payment-content p.address { | ||
| + line-height: 1.6; | ||
| +} | ||
| + | ||
| +.payment-content p.address br { | ||
| + display: block; | ||
| +} | ||
| + | ||
| +p { | ||
| + margin: 0 0 8px 0; | ||
| +} | ||
| + | ||
| +form p:not(:first-of-type) { | ||
| + display: flex; | ||
| + flex-direction: column; | ||
| +} | ||
| + | ||
| +/* Full-width elements in form */ | ||
| +form p:nth-of-type(1), | ||
| +form p:nth-of-type(2), | ||
| +form p:nth-of-type(3), | ||
| +form p:nth-of-type(10), | ||
| +form p:nth-of-type(11), | ||
| +form p:nth-of-type(12) { | ||
| + grid-column: span 2; | ||
| +} | ||
| + | ||
| +label { | ||
| + font-size: 0.85rem; | ||
| + font-weight: bold; | ||
| + margin-bottom: 2px; | ||
| +} | ||
| + | ||
| +input, select { | ||
| + width: 100%; | ||
| + box-sizing: border-box; | ||
| + padding: 6px; | ||
| + font-size: 0.9rem; | ||
| + border: 1px solid #ccc; | ||
| + border-radius: 4px; | ||
| +} | ||
| + | ||
| +button { | ||
| + background-color: #007bff; | ||
| + color: white; | ||
| + border: none; | ||
| + cursor: pointer; | ||
| + font-weight: bold; | ||
| + padding: 10px 30px; | ||
| + margin: 10px auto 0 auto; | ||
| + transition: background 0.2s; | ||
| + width: auto; | ||
| + display: block; | ||
| + border-radius: 4px; | ||
| + font-size: 0.9rem; | ||
| +} | ||
| + | ||
| +button:hover { | ||
| + background-color: #0056b3; | ||
| +} | ||
| + | ||
| +br { | ||
| + display: none; | ||
| +} | ||
| + | ||
| +.payment-content section { | ||
| + border-top: 1px solid #eee; | ||
| + padding-top: 1em; | ||
| + margin-top: 1em; | ||
| +} | ||
| + | ||
| +/* Remove the box around the 'Try again' form on the payment page */ | ||
| +.payment-content form { | ||
| + border: none; | ||
| + background: none; | ||
| + padding: 0; | ||
| + display: block; | ||
| +} | ||
| + | ||
| +.payment-content h3 { | ||
| + margin-bottom: 2em; | ||
| +} | ||
| + | ||
| +.payment-content table { | ||
| + width: 100%; | ||
| + border-collapse: collapse; | ||
| + margin-top: 2em; | ||
| +} | ||
| + | ||
| +.payment-content td:last-child { | ||
| + text-align: right; | ||
| +} | ||
| + | ||
| +.payment-content tr:last-child > td { | ||
| + border-top: 2px solid #333; | ||
| + padding-top: .5em; | ||
| +} | ||
| + | ||
| +.payment-content tr:nth-last-child(2) > td { | ||
| + padding-bottom: .5em; | ||
| +} | ||
| + | ||
| +<?php | ||
| +function getHomeDirectory() { | ||
| + $result = ''; | ||
| + | ||
| + if( function_exists( 'posix_getpwnam' ) ) { | ||
| + $homedir = posix_getpwnam( get_current_user() ); | ||
| + | ||
| + if( !empty( $homedir[ 'dir' ] ) ) { | ||
| + $result = $homedir[ 'dir' ]; | ||
| + } | ||
| + } | ||
| + | ||
| + if( empty( $result ) ) { | ||
| + if( !empty( $_SERVER[ 'HOME' ] ) ) { | ||
| + $result = $_SERVER[ 'HOME' ]; | ||
| + } | ||
| + elseif( !empty( getenv( 'HOME' ) ) ) { | ||
| + $result = getenv( 'HOME' ); | ||
| + } | ||
| + elseif( function_exists( 'posix_getpwuid' ) && | ||
| + function_exists( 'posix_getuid' ) ) { | ||
| + $userInfo = posix_getpwuid( posix_getuid() ); | ||
| + | ||
| + if( !empty( $userInfo[ 'dir' ] ) ) { | ||
| + $result = $userInfo[ 'dir' ]; | ||
| + } | ||
| + } | ||
| + } | ||
| + return $result; | ||
| +} | ||
| + | ||
| +$configPath = getHomeDirectory() . '/.keys/lulu.config'; | ||
| +$config = json_decode( file_get_contents( $configPath ), true ); | ||
| + | ||
| +define( 'CLIENT_KEY', $config[ 'CLIENT_KEY' ] ); | ||
| +define( 'URL_BASE', $config[ 'URL_BASE' ] ); | ||
| +define( 'ORDER_PAGE_COUNT', $config[ 'ORDER_PAGE_COUNT' ] ); | ||
| +define( 'ORDER_PACKAGE', $config[ 'ORDER_PACKAGE' ] ); | ||
| +define( 'ORDER_QUANTITY', $config[ 'ORDER_QUANTITY' ] ); | ||
| +define( 'ORDER_SHIPPING', $config[ 'ORDER_SHIPPING' ] ); | ||
| + | ||
| +const URL_AUTH = URL_BASE . "auth/realms/glasstree/protocol/openid-connect/token"; | ||
| +const URL_COST = URL_BASE . "print-job-cost-calculations/"; | ||
| + | ||
| +const CURRENCY_MAP = [ | ||
| + 'AU'=>'AUD','CA'=>'CAD','GB'=>'GBP', | ||
| + 'AT'=>'EUR','BE'=>'EUR','CY'=>'EUR','EE'=>'EUR','FI'=>'EUR','FR'=>'EUR', | ||
| + 'DE'=>'EUR','GR'=>'EUR','IE'=>'EUR','IT'=>'EUR','LV'=>'EUR','LT'=>'EUR', | ||
| + 'LU'=>'EUR','MT'=>'EUR','NL'=>'EUR','PT'=>'EUR','SK'=>'EUR','SI'=>'EUR', | ||
| + 'ES'=>'EUR' | ||
| +]; | ||
| + | ||
| +$required = [ | ||
| + "city", "country", "postcode", "state", "street1", "phone", "name", "email" | ||
| +]; | ||
| +$missing = []; | ||
| + | ||
| +foreach( $required as $f ) { | ||
| + if( empty( $_POST[ $f ] ) ) { | ||
| + $missing[] = $f; | ||
| + } | ||
| +} | ||
| + | ||
| +$code = 0; | ||
| +$raw_response = ""; | ||
| +$error_message = ""; | ||
| + | ||
| +if( empty( $missing ) ) { | ||
| + define( 'KEEP', false ); | ||
| + define( 'UPPER', true ); | ||
| + | ||
| + $fields = [ | ||
| + 'name' => [ 100, KEEP ], | ||
| + 'street1' => [ 100, UPPER ], | ||
| + 'street2' => [ 100, UPPER ], | ||
| + 'city' => [ 50, UPPER ], | ||
| + 'state' => [ 50, UPPER ], | ||
| + 'postcode' => [ 20, UPPER ], | ||
| + 'phone' => [ 20, KEEP ], | ||
| + 'email' => [ 254, KEEP ], | ||
| + 'gifted' => [ 100, KEEP ] | ||
| + ]; | ||
| + | ||
| + $clean = []; | ||
| + | ||
| + foreach( $fields as $f => $cfg ) { | ||
| + $val = mb_substr( trim( $_POST[ $f ] ?? '' ), 0, $cfg[ 0 ], 'UTF-8' ); | ||
| + $transform = [ | ||
| + KEEP => $val, | ||
| + UPPER => mb_strtoupper( $val, 'UTF-8' ) | ||
| + ]; | ||
| + $clean[ $f ] = $transform[ $cfg[ 1 ] ]; | ||
| + } | ||
| + | ||
| + $selected_currency = CURRENCY_MAP[ $_POST[ "country" ] ] ?? 'USD'; | ||
| + | ||
| + $auth_context = stream_context_create( [ | ||
| + "http" => [ | ||
| + "method" => "POST", | ||
| + "header" => "Authorization: Basic " . | ||
| + base64_encode( CLIENT_KEY ) . | ||
| + "\r\nContent-Type: application/x-www-form-urlencoded\r\n", | ||
| + "content" => http_build_query( [ "grant_type" => "client_credentials" ] ), | ||
| + ], | ||
| + ] ); | ||
| + | ||
| + $auth_json = file_get_contents( URL_AUTH, false, $auth_context ); | ||
| + $auth_response = json_decode( $auth_json, 1 ); | ||
| + $token = $auth_response[ "access_token" ] ?? null; | ||
| + | ||
| + if( $token ) { | ||
| + $cost_data = [ | ||
| + "line_items" => [ [ | ||
| + "page_count" => ORDER_PAGE_COUNT, | ||
| + "quantity" => ORDER_QUANTITY, | ||
| + "pod_package_id" => ORDER_PACKAGE | ||
| + ] ], | ||
| + "shipping_address" => [ | ||
| + "phone_number" => $clean[ "phone" ], | ||
| + "name" => $clean[ "name" ], | ||
| + "email" => $clean[ "email" ], | ||
| + "city" => $clean[ "city" ], | ||
| + "country_code" => $_POST[ "country" ], | ||
| + "postcode" => $clean[ "postcode" ], | ||
| + "state_code" => $clean[ "state" ], | ||
| + "street1" => $clean[ "street1" ], | ||
| + "street2" => $clean[ "street2" ], | ||
| + ], | ||
| + "shipping_option" => ORDER_SHIPPING, | ||
| + "currency" => $selected_currency, | ||
| + ]; | ||
| + | ||
| + $cost_context = stream_context_create( [ | ||
| + "http" => [ | ||
| + "method" => "POST", | ||
| + "header" => "Authorization: Bearer $token\r\n" . | ||
| + "Content-Type: application/json\r\n", | ||
| + "content" => json_encode( $cost_data ), | ||
| + "ignore_errors" => true, | ||
| + ], | ||
| + ] ); | ||
| + | ||
| + $raw_response = file_get_contents( URL_COST, false, $cost_context ); | ||
| + | ||
| + if( !empty( $http_response_header ) ) { | ||
| + preg_match( "/\d{3}/", $http_response_header[ 0 ], $m ); | ||
| + $code = intval( $m[ 0 ] ); | ||
| + } | ||
| + | ||
| + $api_data = json_decode( $raw_response, 1 ) ?? []; | ||
| + | ||
| + if( $code !== 201 ) { | ||
| + $error_message = | ||
| + $api_data[ 'shipping_address' ][ 'detail' ][ 'errors' ][ 0 ][ 'message' ] | ||
| + ?? $api_data[ 'detail' ] | ||
| + ?? "An unexpected error occurred (HTTP $code)."; | ||
| + } | ||
| + } else { | ||
| + $error_message = "Authentication failed."; | ||
| + } | ||
| +} | ||
| + | ||
| +function escape( $data ) { | ||
| + if( is_array( $data ) ) { | ||
| + return array_map( 'escape', $data ); | ||
| + } | ||
| + | ||
| + return htmlspecialchars( $data ?? '', ENT_QUOTES, 'UTF-8' ); | ||
| +} | ||
| + | ||
| +$response = escape( array_merge( | ||
| + [ 'form' => $_POST, 'missing' => $missing, 'api_error' => $error_message ], | ||
| + $api_data[ 'shipping_address' ] ?? [], | ||
| + $api_data ?? [] | ||
| +) ); | ||
| +?> | ||
| +<!DOCTYPE html> | ||
| +<html> | ||
| +<head> | ||
| + <meta charset="utf-8"> | ||
| + <title>autónoma – payment</title> | ||
| + <link rel="stylesheet" href="main.css"> | ||
| +</head> | ||
| +<body> | ||
| + <h1>autónoma – payment</h1> | ||
| + <div class="payment-content"> | ||
| + <?php if( !empty( $response[ 'missing' ] ) ) { ?> | ||
| + <h2>Missing fields</h2> | ||
| + <ul> | ||
| + <?php foreach( $response[ 'missing' ] as $m ) { ?> | ||
| + <li><?= $m ?></li> | ||
| + <?php } ?> | ||
| + </ul> | ||
| + <?php } else { ?> | ||
| + <?php if( $code == 201 ) { ?> | ||
| + <h2>Order summary</h2> | ||
| + <section> | ||
| + <p class="address"> | ||
| + <strong><?= $_POST[ 'name' ] ?></strong><br> | ||
| + <?= $response[ 'street1' ] ?><br> | ||
| + <?php if( !empty( $response[ 'street2' ] ) ) { ?> | ||
| + <?= $response[ 'street2' ] ?><br> | ||
| + <?php } ?> | ||
| + <?= $response[ 'city' ] ?> | ||
| + <?= $response[ 'state' ] ?> | ||
| + <?= $response[ 'postcode' ] ?><br> | ||
| + <?= $response[ 'country' ] ?><br> | ||
| + </p> | ||
| + <table> | ||
| + <tr> | ||
| + <td>Book price</td> | ||
| + <td><?= $response[ 'line_item_costs' ][0][ 'total_cost_excl_tax' ] ?> <?= $response[ 'currency' ] ?></td> | ||
| + </tr> | ||
| + <tr> | ||
| + <td>Shipping</td> | ||
| + <td><?= $response[ 'shipping_cost' ][ 'total_cost_excl_tax' ] ?> <?= $response[ 'currency' ] ?></td> | ||
| + </tr> | ||
| + <tr> | ||
| + <td>Taxes</td> | ||
| + <td><?= $response[ 'total_tax' ] ?> <?= $response[ 'currency' ] ?></td> | ||
| + </tr> | ||
| + <tr> | ||
| + <td><strong>Amount due</strong></td> | ||
| + <td><strong><?= $response[ 'total_cost_incl_tax' ] ?> <?= $response[ 'currency' ] ?></strong></td> | ||
| + </tr> | ||
| + </table> | ||
| + </section> | ||
| + <?php } else { ?> | ||
| + <h2>Shipping calculation error</h2> | ||
| + <p><?= $response[ 'api_error' ] ?></p> | ||
| + <form action="."> | ||
| + <button type="submit" onclick="history.back(); return false;"> | ||
| + Try again | ||
| + </button> | ||
| + </form> | ||
| + <?php } ?> | ||
| + <?php } ?> | ||
| + </div> | ||
| +</body> | ||
| +</html> | ||
| + | ||
| Delta | 666 lines added, 0 lines removed, 666-line increase |
|---|