| 1 |
<?php |
| 2 |
/** |
| 3 |
* Ebook Store - PayPal settings tab. |
| 4 |
* |
| 5 |
* PayPal is the free, always-available gateway, so nothing on this tab is |
| 6 |
* Pro-gated. The tab is included inside a plain <div class="ebook-settings-panel"> |
| 7 |
* wrapper, so it emits <section> blocks only - never table rows. |
| 8 |
* |
| 9 |
* PHP 7.4 compatible. |
| 10 |
* |
| 11 |
* @package EbookStore |
| 12 |
*/ |
| 13 |
|
| 14 |
if ( ! defined( 'ABSPATH' ) ) { |
| 15 |
exit; |
| 16 |
} |
| 17 |
|
| 18 |
settings_fields( 'ebook-settings-group-paypal' ); |
| 19 |
do_settings_sections( 'ebook-settings-group-paypal' ); |
| 20 |
|
| 21 |
/* |
| 22 |
* Saved values. |
| 23 |
* |
| 24 |
* The toggles below write either '1' or an empty string, so '1' is the only |
| 25 |
* value that means "on". The sandbox flag is the one exception: the checkout |
| 26 |
* form in functions.php treats anything that is not an empty string as sandbox, |
| 27 |
* so we mirror that rule here to make sure the screen never claims the store is |
| 28 |
* live while checkout is actually pointing at PayPal's test servers. |
| 29 |
*/ |
| 30 |
$paypal_account = trim( (string) get_option( 'paypal_account', '' ) ); |
| 31 |
$paypal_enabled = (string) get_option( 'paypal_integration_enabled', '1' ); |
| 32 |
$paypal_language = (string) get_option( 'paypal_language', '' ); |
| 33 |
$paypal_sandbox = (string) get_option( 'paypal_sandbox', '' ); |
| 34 |
$verify_transactions = (string) get_option( 'paypal_verify_transactions', '' ); |
| 35 |
$allow_echeck = (string) get_option( 'ebook_store_allow_echeck', '' ); |
| 36 |
$require_shipping = (string) get_option( 'ebook_store_require_shipping', '0' ); |
| 37 |
|
| 38 |
$default_return_button_text = ( isset( $op ) && is_object( $op ) && isset( $op->paypal_return_button_text ) ) |
| 39 |
? (string) $op->paypal_return_button_text |
| 40 |
: 'Click here to go to download page'; |
| 41 |
$paypal_return_button_text = (string) get_option( 'paypal_return_button_text', $default_return_button_text ); |
| 42 |
|
| 43 |
$paypal_is_enabled = ( $paypal_enabled === '1' ); |
| 44 |
$paypal_is_sandbox = ( $paypal_sandbox != '' ); // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison -- matches the checkout form. |
| 45 |
// "Never configured" counts as on, matching what the handler actually does. |
| 46 |
$paypal_is_verified = function_exists( 'ebook_store_paypal_verification_enabled' ) |
| 47 |
? ebook_store_paypal_verification_enabled() |
| 48 |
: ( $verify_transactions === '1' ); |
| 49 |
$paypal_echeck_on = ( $allow_echeck === '1' ); |
| 50 |
$paypal_has_account = ( $paypal_account !== '' ); |
| 51 |
|
| 52 |
/* |
| 53 |
* PayPal's own country/language codes for the checkout screen. The list lives in |
| 54 |
* ebook_options.php; fall back to a "let PayPal decide" single entry if this file |
| 55 |
* is ever rendered without it. |
| 56 |
*/ |
| 57 |
$paypal_language_options = ( isset( $lc ) && is_array( $lc ) ) ? $lc : array( '' => '' ); |
| 58 |
$paypal_language_options[''] = __( 'Let PayPal choose automatically (recommended)', 'ebook-store' ); |
| 59 |
|
| 60 |
/* PayPal's no_shipping parameter: 0 = ask but skippable, 1 = never ask, 2 = required. */ |
| 61 |
$shipping_options = array( |
| 62 |
'0' => __( 'Ask for a shipping address, but let the buyer skip it', 'ebook-store' ), |
| 63 |
'1' => __( 'Do not ask for a shipping address (recommended for ebooks)', 'ebook-store' ), |
| 64 |
'2' => __( 'Require a shipping address', 'ebook-store' ), |
| 65 |
); |
| 66 |
|
| 67 |
$general_tab_url = function_exists( 'ebook_store_get_settings_tab_url' ) ? ebook_store_get_settings_tab_url( 'General' ) : ''; |
| 68 |
$templates_tab_url = function_exists( 'ebook_store_get_settings_tab_url' ) ? ebook_store_get_settings_tab_url( 'Templates' ) : ''; |
| 69 |
|
| 70 |
ebook_store_render_hero( |
| 71 |
array( |
| 72 |
'eyebrow' => __( 'PayPal', 'ebook-store' ), |
| 73 |
'title' => __( 'Take payments for your ebooks through PayPal', 'ebook-store' ), |
| 74 |
'intro' => __( 'Tell Ebook Store which PayPal account should receive the money, choose what buyers see on the button and on PayPal\'s pages, and decide how carefully each payment is checked before the download is released.', 'ebook-store' ), |
| 75 |
'aside' => function () use ( $paypal_is_enabled, $paypal_has_account, $paypal_account, $paypal_is_sandbox, $paypal_is_verified, $paypal_echeck_on ) { |
| 76 |
?> |
| 77 |
<aside class="ebook-settings-status-card"> |
| 78 |
<h4><?php echo esc_html__( 'Current status', 'ebook-store' ); ?></h4> |
| 79 |
<ul class="ebook-settings-status-list"> |
| 80 |
<?php |
| 81 |
ebook_store_status_row( |
| 82 |
__( 'PayPal button', 'ebook-store' ), |
| 83 |
$paypal_is_enabled ? ( $paypal_has_account ? 'ok' : 'warn' ) : 'muted', |
| 84 |
$paypal_is_enabled |
| 85 |
? ( $paypal_has_account |
| 86 |
? __( 'Buyers can see and use the PayPal button.', 'ebook-store' ) |
| 87 |
: __( 'Turned on, but the PayPal account email below is still empty.', 'ebook-store' ) ) |
| 88 |
: __( 'Turned off. Buyers will not see a PayPal button.', 'ebook-store' ) |
| 89 |
); |
| 90 |
|
| 91 |
ebook_store_status_row( |
| 92 |
__( 'Receiving account', 'ebook-store' ), |
| 93 |
$paypal_has_account ? 'ok' : 'error', |
| 94 |
$paypal_has_account |
| 95 |
? sprintf( |
| 96 |
/* translators: %s: the PayPal account email address money is sent to. */ |
| 97 |
__( 'Money goes to %s.', 'ebook-store' ), |
| 98 |
$paypal_account |
| 99 |
) |
| 100 |
: __( 'No PayPal email saved, so PayPal checkout cannot work at all.', 'ebook-store' ), |
| 101 |
$paypal_has_account |
| 102 |
? array() |
| 103 |
: array( |
| 104 |
'label' => __( 'Add it now', 'ebook-store' ), |
| 105 |
'url' => '#paypal_account', |
| 106 |
) |
| 107 |
); |
| 108 |
|
| 109 |
ebook_store_status_row( |
| 110 |
__( 'Mode', 'ebook-store' ), |
| 111 |
$paypal_is_sandbox ? 'warn' : 'ok', |
| 112 |
$paypal_is_sandbox |
| 113 |
? __( 'Sandbox. Checkout uses PayPal\'s test servers, so no real money is taken.', 'ebook-store' ) |
| 114 |
: __( 'Live. Real payments are being taken.', 'ebook-store' ) |
| 115 |
); |
| 116 |
|
| 117 |
ebook_store_status_row( |
| 118 |
__( 'Payment checking', 'ebook-store' ), |
| 119 |
$paypal_is_verified ? 'ok' : 'warn', |
| 120 |
$paypal_is_verified |
| 121 |
? __( 'Every payment message is confirmed with PayPal before a download is released.', 'ebook-store' ) |
| 122 |
: __( 'Off. Payment messages are trusted without asking PayPal to confirm them.', 'ebook-store' ) |
| 123 |
); |
| 124 |
|
| 125 |
ebook_store_status_row( |
| 126 |
__( 'eCheck payments', 'ebook-store' ), |
| 127 |
$paypal_echeck_on ? 'warn' : 'muted', |
| 128 |
$paypal_echeck_on |
| 129 |
? __( 'Accepted. Those orders can take several days to clear before delivery.', 'ebook-store' ) |
| 130 |
: __( 'Not accepted. Buyers pay with methods that clear straight away.', 'ebook-store' ) |
| 131 |
); |
| 132 |
?> |
| 133 |
</ul> |
| 134 |
</aside> |
| 135 |
<?php |
| 136 |
}, |
| 137 |
) |
| 138 |
); |
| 139 |
|
| 140 |
ebook_store_section_open( |
| 141 |
array( |
| 142 |
'eyebrow' => __( 'Account', 'ebook-store' ), |
| 143 |
'title' => __( 'Where the money goes', 'ebook-store' ), |
| 144 |
'intro' => __( 'These two settings decide which PayPal account is paid and which language PayPal shows your buyers.', 'ebook-store' ), |
| 145 |
'id' => 'ebook-paypal-account', |
| 146 |
) |
| 147 |
); |
| 148 |
|
| 149 |
ebook_store_toggle_grid_open(); |
| 150 |
ebook_store_toggle( |
| 151 |
array( |
| 152 |
'name' => 'paypal_integration_enabled', |
| 153 |
'title' => __( 'Offer PayPal at checkout', 'ebook-store' ), |
| 154 |
'description' => __( 'When this is on, buyers see a PayPal button on your ebooks. Turn it off if you only want to sell through another payment method.', 'ebook-store' ), |
| 155 |
'checked' => $paypal_is_enabled ? '1' : '', |
| 156 |
) |
| 157 |
); |
| 158 |
ebook_store_toggle_grid_close(); |
| 159 |
|
| 160 |
ebook_store_grid_open( 2 ); |
| 161 |
ebook_store_field( |
| 162 |
array( |
| 163 |
'type' => 'email', |
| 164 |
'name' => 'paypal_account', |
| 165 |
'label' => __( 'PayPal account email address', 'ebook-store' ), |
| 166 |
'value' => $paypal_account, |
| 167 |
'placeholder' => 'you@example.com', |
| 168 |
'help' => __( 'The email address you use to sign in to PayPal. Every ebook payment is sent to this account. If it is empty or misspelled, buyers either see an error at PayPal or pay the wrong person, so copy it straight from your PayPal profile.', 'ebook-store' ), |
| 169 |
'note' => $paypal_has_account ? '' : esc_html__( 'PayPal checkout will not work until you fill this in.', 'ebook-store' ), |
| 170 |
'note_tone' => 'error', |
| 171 |
) |
| 172 |
); |
| 173 |
|
| 174 |
ebook_store_field( |
| 175 |
array( |
| 176 |
'type' => 'select', |
| 177 |
'name' => 'paypal_language', |
| 178 |
'label' => __( 'Language PayPal shows your buyers', 'ebook-store' ), |
| 179 |
'value' => $paypal_language, |
| 180 |
'options' => $paypal_language_options, |
| 181 |
'help' => __( 'Leave this on the automatic setting and PayPal will use each buyer\'s own language. Only pick a country or language if all of your customers are in one place and you want PayPal\'s pages to match your site.', 'ebook-store' ), |
| 182 |
) |
| 183 |
); |
| 184 |
ebook_store_grid_close(); |
| 185 |
|
| 186 |
ebook_store_callout( |
| 187 |
sprintf( |
| 188 |
/* translators: 1: opening link tag to PayPal's IPN settings, 2: closing link tag. */ |
| 189 |
__( 'Ebook Store only knows a payment succeeded because PayPal sends it a confirmation message (called IPN). %1$sTurn IPN on in your PayPal profile%2$s. You do not need to paste a URL anywhere: the plugin sends the correct address with every order. If IPN is off, buyers pay but never get their download.', 'ebook-store' ), |
| 190 |
'<a href="https://www.paypal.com/cgi-bin/customerprofileweb?cmd=%5fprofile%2dipn%2dnotify" target="_blank" rel="noopener noreferrer">', |
| 191 |
'</a>' |
| 192 |
), |
| 193 |
'warning', |
| 194 |
__( 'Do this first:', 'ebook-store' ) |
| 195 |
); |
| 196 |
|
| 197 |
if ( $general_tab_url !== '' ) { |
| 198 |
ebook_store_callout( |
| 199 |
sprintf( |
| 200 |
/* translators: 1: opening link tag to the General settings tab, 2: closing link tag. */ |
| 201 |
__( 'The currency buyers are charged in is not set here. It lives on the %1$sGeneral tab%2$s, together with your prices and tax rate. Make sure the currency you chose there is one your PayPal account can accept.', 'ebook-store' ), |
| 202 |
'<a href="' . esc_url( $general_tab_url ) . '">', |
| 203 |
'</a>' |
| 204 |
), |
| 205 |
'soft' |
| 206 |
); |
| 207 |
} |
| 208 |
|
| 209 |
ebook_store_section_close(); |
| 210 |
|
| 211 |
ebook_store_section_open( |
| 212 |
array( |
| 213 |
'eyebrow' => __( 'Buy button', 'ebook-store' ), |
| 214 |
'title' => __( 'What the PayPal button says', 'ebook-store' ), |
| 215 |
'intro' => __( 'This is the wording buyers click on your site to start paying. Short, clear wording sells more copies than clever wording.', 'ebook-store' ), |
| 216 |
'id' => 'ebook-paypal-button-text', |
| 217 |
) |
| 218 |
); |
| 219 |
|
| 220 |
ebook_store_advanced_open( __( 'Advanced button options', 'ebook-store' ) ); |
| 221 |
|
| 222 |
ebook_store_grid_open( 2 ); |
| 223 |
ebook_store_render_gateway_button_text( 'paypal' ); |
| 224 |
ebook_store_grid_close(); |
| 225 |
|
| 226 |
ebook_store_advanced_close(); |
| 227 |
|
| 228 |
ebook_store_section_close(); |
| 229 |
|
| 230 |
ebook_store_section_open( |
| 231 |
array( |
| 232 |
'eyebrow' => __( 'After payment', 'ebook-store' ), |
| 233 |
'title' => __( 'Sending buyers back to your site', 'ebook-store' ), |
| 234 |
'intro' => __( 'Once PayPal has taken the payment it shows a button that brings the buyer back to your download page. You choose the wording on that button.', 'ebook-store' ), |
| 235 |
'id' => 'ebook-paypal-return', |
| 236 |
) |
| 237 |
); |
| 238 |
|
| 239 |
ebook_store_advanced_open( __( 'Advanced return-button options', 'ebook-store' ) ); |
| 240 |
|
| 241 |
ebook_store_grid_open( 2 ); |
| 242 |
ebook_store_field( |
| 243 |
array( |
| 244 |
'type' => 'text', |
| 245 |
'name' => 'paypal_return_button_text', |
| 246 |
'label' => __( 'Wording on PayPal\'s return button', 'ebook-store' ), |
| 247 |
'value' => $paypal_return_button_text, |
| 248 |
'placeholder' => $default_return_button_text, |
| 249 |
'wide' => true, |
| 250 |
'help' => __( 'Tell the buyer exactly what happens next, for example "Click here to go to your download page". Keep it short: PayPal cuts off long text. Vague wording such as "Continue" is the single biggest cause of "where is my ebook?" emails.', 'ebook-store' ), |
| 251 |
) |
| 252 |
); |
| 253 |
|
| 254 |
if ( $templates_tab_url !== '' ) { |
| 255 |
ebook_store_steps( |
| 256 |
__( 'What the buyer sees', 'ebook-store' ), |
| 257 |
array( |
| 258 |
esc_html__( 'They click your PayPal button and pay on PayPal\'s website.', 'ebook-store' ), |
| 259 |
esc_html__( 'PayPal shows this button and they click it.', 'ebook-store' ), |
| 260 |
sprintf( |
| 261 |
/* translators: 1: opening link tag to the Templates settings tab, 2: closing link tag. */ |
| 262 |
__( 'They land on the download page you picked on the %1$sTemplates tab%2$s. If no page is set there, they have nowhere to land.', 'ebook-store' ), |
| 263 |
'<a href="' . esc_url( $templates_tab_url ) . '">', |
| 264 |
'</a>' |
| 265 |
), |
| 266 |
) |
| 267 |
); |
| 268 |
} |
| 269 |
ebook_store_grid_close(); |
| 270 |
|
| 271 |
ebook_store_advanced_close(); |
| 272 |
|
| 273 |
ebook_store_section_close(); |
| 274 |
|
| 275 |
ebook_store_section_open( |
| 276 |
array( |
| 277 |
'eyebrow' => __( 'Testing and safety', 'ebook-store' ), |
| 278 |
'title' => __( 'Test mode and payment checking', 'ebook-store' ), |
| 279 |
'intro' => __( 'Use test mode to try a purchase without spending real money, and leave payment checking on so downloads are only released for payments PayPal has confirmed.', 'ebook-store' ), |
| 280 |
'id' => 'ebook-paypal-testing', |
| 281 |
) |
| 282 |
); |
| 283 |
|
| 284 |
ebook_store_advanced_open( __( 'Advanced testing options', 'ebook-store' ) ); |
| 285 |
|
| 286 |
ebook_store_toggle_grid_open(); |
| 287 |
ebook_store_toggle( |
| 288 |
array( |
| 289 |
'name' => 'paypal_sandbox', |
| 290 |
'title' => __( 'Use PayPal test mode (sandbox)', 'ebook-store' ), |
| 291 |
'description' => __( 'Sends checkout to PayPal\'s practice website so you can buy your own ebook without paying. Remember to turn it back off: while it is on, real customers cannot pay you.', 'ebook-store' ), |
| 292 |
'checked' => $paypal_is_sandbox ? '1' : '', |
| 293 |
) |
| 294 |
); |
| 295 |
|
| 296 |
ebook_store_toggle( |
| 297 |
array( |
| 298 |
'name' => 'paypal_verify_transactions', |
| 299 |
'title' => __( 'Confirm every payment with PayPal', 'ebook-store' ), |
| 300 |
'description' => __( 'Before releasing a download, ask PayPal whether the payment message really came from PayPal. Leave this on. With it off, a faked payment message could unlock your ebook for free.', 'ebook-store' ), |
| 301 |
'checked' => $paypal_is_verified ? '1' : '', |
| 302 |
) |
| 303 |
); |
| 304 |
ebook_store_toggle_grid_close(); |
| 305 |
|
| 306 |
ebook_store_grid_open( 2 ); |
| 307 |
|
| 308 |
ebook_store_steps( |
| 309 |
__( 'How to run a test purchase', 'ebook-store' ), |
| 310 |
array( |
| 311 |
sprintf( |
| 312 |
/* translators: 1: opening link tag to PayPal's developer site, 2: closing link tag. */ |
| 313 |
__( 'Create free test accounts on the %1$sPayPal developer site%2$s. They are completely separate from your real PayPal account.', 'ebook-store' ), |
| 314 |
'<a href="https://developer.paypal.com/developer/accounts/" target="_blank" rel="noopener noreferrer">', |
| 315 |
'</a>' |
| 316 |
), |
| 317 |
esc_html__( 'Turn on test mode above, put your test seller email in the account field, and save.', 'ebook-store' ), |
| 318 |
esc_html__( 'Buy one of your own ebooks with the test buyer account and check that the download arrives. Test confirmations can take a few minutes longer than real ones.', 'ebook-store' ), |
| 319 |
esc_html__( 'Turn test mode back off and put your real PayPal email back before you tell customers about the store.', 'ebook-store' ), |
| 320 |
) |
| 321 |
); |
| 322 |
|
| 323 |
ebook_store_callout( |
| 324 |
__( 'Only turn payment checking off if your web host blocks outgoing connections to PayPal and paid orders are getting stuck. It is a temporary workaround, not a setting to leave off.', 'ebook-store' ), |
| 325 |
'warning', |
| 326 |
__( 'One exception:', 'ebook-store' ) |
| 327 |
); |
| 328 |
|
| 329 |
ebook_store_grid_close(); |
| 330 |
|
| 331 |
ebook_store_advanced_close(); |
| 332 |
|
| 333 |
ebook_store_section_close(); |
| 334 |
|
| 335 |
ebook_store_section_open( |
| 336 |
array( |
| 337 |
'eyebrow' => __( 'Buyer prompts', 'ebook-store' ), |
| 338 |
'title' => __( 'eCheck payments and shipping address', 'ebook-store' ), |
| 339 |
'intro' => __( 'Two choices about what PayPal asks your buyers for, and how long you wait for the money.', 'ebook-store' ), |
| 340 |
'id' => 'ebook-paypal-buyer-prompts', |
| 341 |
) |
| 342 |
); |
| 343 |
|
| 344 |
ebook_store_advanced_open( __( 'Advanced buyer-prompt options', 'ebook-store' ) ); |
| 345 |
|
| 346 |
ebook_store_toggle_grid_open(); |
| 347 |
ebook_store_toggle( |
| 348 |
array( |
| 349 |
'name' => 'ebook_store_allow_echeck', |
| 350 |
'title' => __( 'Accept eCheck payments', 'ebook-store' ), |
| 351 |
'description' => __( 'An eCheck is a bank transfer that can take several working days to clear. The buyer does not get the ebook until it clears, which often leads to complaints. Most ebook shops leave this off.', 'ebook-store' ), |
| 352 |
'checked' => $paypal_echeck_on ? '1' : '', |
| 353 |
) |
| 354 |
); |
| 355 |
ebook_store_toggle_grid_close(); |
| 356 |
|
| 357 |
ebook_store_grid_open( 2 ); |
| 358 |
ebook_store_field( |
| 359 |
array( |
| 360 |
'type' => 'select', |
| 361 |
'name' => 'ebook_store_require_shipping', |
| 362 |
'label' => __( 'Shipping address at PayPal checkout', 'ebook-store' ), |
| 363 |
'value' => $require_shipping, |
| 364 |
'options' => $shipping_options, |
| 365 |
'help' => __( 'An ebook is downloaded, never posted, so there is nothing to ship. Choosing not to ask keeps checkout short and fewer buyers give up halfway. Pick "Require a shipping address" only if your bookkeeping or tax rules need the buyer\'s address on file.', 'ebook-store' ), |
| 366 |
) |
| 367 |
); |
| 368 |
|
| 369 |
ebook_store_callout( |
| 370 |
sprintf( |
| 371 |
/* translators: 1: opening link tag to PayPal's eCheck help page, 2: closing link tag. */ |
| 372 |
__( 'Not sure about eChecks? %1$sPayPal explains how they work%2$s. The short version: the money is on its way but is not in your account yet, and your buyer is waiting for a book they have already paid for.', 'ebook-store' ), |
| 373 |
'<a href="https://www.paypal.com/us/selfhelp/article/What-is-an-eCheck-FAQ1082" target="_blank" rel="noopener noreferrer">', |
| 374 |
'</a>' |
| 375 |
), |
| 376 |
'soft' |
| 377 |
); |
| 378 |
ebook_store_grid_close(); |
| 379 |
|
| 380 |
ebook_store_advanced_close(); |
| 381 |
|
| 382 |
ebook_store_section_close(); |
| 383 |
|