Passed
Push — master ( 5f2bd1...7c2064 )
by
unknown
13:34
created

wp_esc_attr()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
// This script contains the internal API that routes between the submission form
3
// and stripe.
4
5
function donate_post_api($token, $url, $data, $type, $headers = [])
6
{
7
    $headers = array_merge($headers, ["Authorization: Bearer $token"]);
8
    if ($type == "json") {
9
        $data = json_encode($data);
10
        $headers[] = "Accept: application/json";
11
        $headers[] = "Content-Type: application/json";
12
    } elseif ($type == "html") {
13
        $headers[] = "Content-Type: application/x-www-form-urlencoded";
14
        $data = http_build_query($data);
15
    }
16
    $options = [
17
        "http" => [
18
            "header" => $headers,
19
            "method" => "POST",
20
            "content" => $data,
21
            "ignore_errors" => true,
22
        ],
23
    ];
24
    $context = stream_context_create($options);
25
    $result = file_get_contents($url, false, $context);
26
    $result = json_decode($result);
27
    return $result;
28
}
29
30
function donate_amount()
31
{
32
    $amount = $_POST["how-much"];
33
    if ($amount == "other") {
34
        $amount = $_POST["how-much-other"];
35
    }
36
    return $amount;
37
}
38
39
function giftaid_decision()
40
{
41
    if (isset($_POST["gift-aid"])) {
42
        return "Yes";
43
    } else {
44
        return "No";
45
    }
46
}
47
48
# Stripe
49
50
function stripe_post($path, $data)
51
{
52
    $result = donate_post_api(
53
        STRIPE_DONATE_SECRET_KEY,
0 ignored issues
show
Bug introduced by
The constant STRIPE_DONATE_SECRET_KEY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
54
        "https://api.stripe.com/v1" . $path,
55
        $data,
56
        "html"
57
    );
58
    if (isset($result->error)) {
59
        return "Sorry, there was an error processing your donation: {$result->error->message}. Please try again.";
60
    }
61
    return $result;
62
}
63
64
function stripe_session_ajax($successPage, $cancelPage)
65
{
66
    $amount = donate_amount();
67
    $giftaid = giftaid_decision();
68
    $howoften = $_POST["how-often"];
69
    $utm_source = $_POST["utm_source"];
70
    $utm_content = $_POST["utm_content"];
71
    $utm_medium = $_POST["utm_medium"];
72
    $utm_campaign = $_POST["utm_campaign"];
73
    $full_name = $_POST["full_name"];
74
    $contact_permission = $_POST["contact_permission"] ?? "No";
75
76
    # backward compatibility
77
    if ($howoften == "recurring") {
78
        $howoften = "monthly";
79
    }
80
    $validPeriods = ["monthly" => "month", "annually" => "year"];
81
    $period = $validPeriods[$howoften] ?? "once";
82
83
    $metadata = [
84
        "gift-aid" => $giftaid,
85
        "gift-aid-name" => $full_name,
86
        "utm_source" => $utm_source,
87
        "utm_content" => $utm_content,
88
        "utm_medium" => $utm_medium,
89
        "utm_campaign" => $utm_campaign,
90
        "contact_permission" => $contact_permission,
91
    ];
92
    // set billing addres var to required if giftaid is true
93
    if ($giftaid == "Yes") {
94
        $collectBilling = "required";
95
        $name = "Donation to mySociety (with gift aid)";
96
    } else {
97
        $collectBilling = "auto";
98
        $name = "Donation to mySociety";
99
    }
100
    $data = [
101
        "payment_method_types" => ["card", "bacs_debit", "paypal"],
102
        "success_url" => $successPage,
103
        "cancel_url" => $cancelPage,
104
        "billing_address_collection" => $collectBilling,
105
    ];
106
107
    $mysocDesc = "
108
    mySociety is a charity committed to making a fairer society 
109
    by providing digital services, research and data, openly and 
110
    at no cost. We use technology to help people understand and 
111
    take part in the decisions that affect their lives and communities.
112
    We run services such as TheyWorkForYou, WhatDoTheyKnow and FixMyStreet.
113
    ";
114
115
    if ($period == "once") {
116
        // one off payments
117
        $data += [
118
            "mode" => "payment",
119
            "payment_intent_data" => [
120
                "metadata" => $metadata,
121
            ],
122
            "submit_type" => "donate",
123
            "line_items" => [
124
                [
125
                    "amount" => $amount * 100,
126
                    "currency" => "gbp",
127
                    "name" => $name,
128
                    "description" => $mysocDesc,
129
                    "quantity" => 1,
130
                ],
131
            ],
132
        ];
133
    } else {
134
        // recurring subscription payments
135
        $data += [
136
            "mode" => "subscription",
137
            "subscription_data" => [
138
                "metadata" => $metadata,
139
            ],
140
            "line_items" => [
141
                [
142
                    "price_data" => [
143
                        "unit_amount" => $amount * 100,
144
                        "currency" => "gbp",
145
                        "product_data" => [
146
                            "name" => $name,
147
                            "description" => $mysocDesc,
148
                        ],
149
                        "recurring" => ["interval" => $period],
150
                    ],
151
                    "quantity" => 1,
152
                ],
153
            ],
154
        ];
155
    }
156
    $result = stripe_post("/checkout/sessions", $data);
157
    if (is_string($result)) {
158
        return ["error" => $result];
159
    } else {
160
        return $result;
161
    }
162
}
163
164
function verify_recaptcha()
165
{
166
    $url = "https://www.google.com/recaptcha/api/siteverify";
167
    $data = [
168
        "secret" => OPTION_RECAPTCHA_SECRET,
0 ignored issues
show
Bug introduced by
The constant OPTION_RECAPTCHA_SECRET was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
169
        "response" => $_POST["g-recaptcha-response"],
170
    ];
171
    $headers = ["Content-Type: application/x-www-form-urlencoded"];
172
173
    $options = [
174
        "http" => [
175
            "header" => $headers,
176
            "method" => "POST",
177
            "content" => http_build_query($data),
178
            "ignore_errors" => true,
179
        ],
180
    ];
181
    $context = stream_context_create($options);
182
    $result = file_get_contents($url, false, $context);
183
    $result = json_decode($result);
184
    if ($result->success) {
185
        return;
186
    }
187
    return join(", ", $result->{'error-codes'});
188
}
189
190
function check_for_stripe_submission(
191
    $successPage = "https://www.mysociety.org/donate/donation-thanks/",
192
    $cancelPage = "https://www.mysociety.org/donate/donation-cancelled/"
193
) {
194
    // If a get request with a stripe parameter
195
    // Run the script session and return either
196
    // the success json or an error
197
    if (isset($_GET["stripe"]) && $_GET["stripe"]) {
198
        $error = verify_recaptcha();
199
        if ($error) {
200
            $result = ["error" => $error];
201
        } else {
202
            $result = stripe_session_ajax($successPage, $cancelPage);
203
        }
204
        header("Content-Type: application/json");
205
        print json_encode($result);
206
        exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
207
    }
208
}
209
210
function get_checked($value, $checked_value, $echo = true)
211
{
212
    $checked = $value == $checked_value ? 'checked="checked"' : "";
213
214
    if ($echo) {
215
        echo $checked;
216
    } else {
217
        return $checked;
218
    }
219
}
220
221
function wp_esc_attr($text)
222
{
223
    return htmlspecialchars($text, ENT_QUOTES, "UTF-8");
224
}