Making WordPress.org

Changeset 7042


Ignore:
Timestamp:
04/05/2018 10:47:27 PM (8 years ago)
Author:
iandunn
Message:

Stripe Client: Add more granular error messages to help troubleshoot.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/utilities/class-stripe-client.php

    r6598 r7042  
    1616class Stripe_Client {
    1717    const API_URL = 'https://api.stripe.com';
     18    const AMOUNT_MAX = 99999999;
    1819    protected $secret_key;
    1920
     
    3637     *
    3738     * @return object
     39     *
    3840     * @throws Exception
    3941     */
     
    5557        );
    5658
     59        /**
     60         * Stripe doesn't allow amounts larger than `AMOUNT_MAX`, even in currencies where that's the equivalent of less than $5k USD.
     61         *
     62         * The amount in the error message is converted back to the base unit, to avoid confusing the user.
     63         *
     64         * See https://botbot.me/freenode/stripe/msg/47523902/.
     65         * See https://stripe.com/docs/currencies#minimum-and-maximum-charge-amounts.
     66         */
     67        if ( isset( $request_args['body']['amount'] ) && $request_args['body']['amount'] > self::AMOUNT_MAX ) {
     68            throw new Exception( sprintf(
     69                __( "We're sorry, but we can't accept amounts larger than %s. Please send the equivalent in USD, or break it up into several smaller payments. Feel free to email <a href='mailto:%s'>%s</a> with any questions.", 'wordcamporg' ),
     70                number_format( self::AMOUNT_MAX / self::get_fractional_unit_multiplier( $request_args['body']['currency'] ), 2 ),
     71                EMAIL_CENTRAL_SUPPORT,
     72                EMAIL_CENTRAL_SUPPORT
     73            ) );
     74        }
     75
    5776        $response = wp_remote_post( self::API_URL . '/v1/charges', $request_args );
    5877
    5978        if ( is_wp_error( $response ) ) {
    60             Logger\log( 'response_error', $response );
     79            Logger\log( 'response_error', compact( 'response' ) );
    6180            throw new Exception( $response->get_error_message() );
    6281        }
     
    6483        $body = json_decode( wp_remote_retrieve_body( $response ) );
    6584
     85        /*
     86         * Declined cards are the most common type of error, so informing the user that it was declined should
     87         * significantly cut down on support requests.
     88         */
     89        if ( isset( $body->error->type ) && 'card_error' === $body->error->type ) {
     90            throw new Exception( sprintf(
     91                __( "We're sorry, but that card was declined by the issuer, please try another. You can also contact the card issuer to find out why they declined it, or email <a href='mailto:%s'>%s</a> with any other questions.", 'wordcamporg' ),
     92                EMAIL_CENTRAL_SUPPORT,
     93                EMAIL_CENTRAL_SUPPORT
     94            ) );
     95        }
     96
    6697        if ( empty( $body->id ) || empty( $body->paid ) || ! $body->paid ) {
    67             Logger\log( 'unexpected_response_body', $response );
    68             throw new Exception( 'Unexpected response body.' );
     98            Logger\log( 'unexpected_response_body', compact( 'response' ) );
     99            throw new Exception( sprintf(
     100                __( "We're sorry, but we encountered an error trying to process that transaction. Please email <a href='mailto:%s'>%s</a> for help.", 'wordcamporg' ),
     101                EMAIL_CENTRAL_SUPPORT,
     102                EMAIL_CENTRAL_SUPPORT
     103            ) );
    69104        }
    70105
    71106        return $body;
    72107    }
     108
     109    /**
     110     * Get the multiplier needed to convert a currency's base unit to its equivalent fractional unit.
     111     *
     112     * Stripe wants amounts in the fractional unit (e.g., pennies), not the base unit (e.g., dollars). Zero-decimal
     113     * currencies are not included here, because they're not supported at all yet.
     114     *
     115     * The data here comes from https://en.wikipedia.org/wiki/List_of_circulating_currencies.
     116     *
     117     * @param string $order_currency
     118     *
     119     * @return int
     120     *
     121     * @throws Exception
     122     */
     123    public static function get_fractional_unit_multiplier( $order_currency ) {
     124        $match = null;
     125
     126        $currency_multipliers = array(
     127            5    => array( 'MRO', 'MRU' ),
     128            100  => array(
     129                'AED', 'AFN', 'ALL', 'AMD', 'ANG', 'AOA', 'ARS', 'AUD', 'AWG', 'AZN', 'BAM', 'BBD', 'BDT', 'BGN',
     130                'BMD', 'BND', 'BOB', 'BRL', 'BSD', 'BTN', 'BWP', 'BYN', 'BZD', 'CAD', 'CDF', 'CHF', 'CNY', 'COP',
     131                'CRC', 'CUC', 'CUP', 'CVE', 'CZK', 'DKK', 'DOP', 'DZD', 'EGP', 'ERN', 'ETB', 'EUR', 'FJD', 'FKP',
     132                'GBP', 'GEL', 'GGP', 'GHS', 'GIP', 'GMD', 'GTQ', 'GYD', 'HKD', 'HNL', 'HRK', 'HTG', 'HUF', 'IDR',
     133                'ILS', 'IMP', 'INR', 'IRR', 'ISK', 'JEP', 'JMD', 'JOD', 'KES', 'KGS', 'KHR', 'KPW', 'KYD', 'KZT',
     134                'LAK', 'LBP', 'LKR', 'LRD', 'LSL', 'MAD', 'MDL', 'MKD', 'MMK', 'MNT', 'MOP', 'MUR', 'MVR', 'MWK',
     135                'MXN', 'MYR', 'MZN', 'NAD', 'NGN', 'NIO', 'NOK', 'NPR', 'NZD', 'PAB', 'PEN', 'PGK', 'PHP', 'PKR',
     136                'PLN', 'PRB', 'QAR', 'RON', 'RSD', 'RUB', 'SAR', 'SBD', 'SCR', 'SDG', 'SEK', 'SGD', 'SHP', 'SLL',
     137                'SOS', 'SRD', 'SSP', 'STD', 'SYP', 'SZL', 'THB', 'TJS', 'TMT', 'TOP', 'TRY', 'TTD', 'TVD', 'TWD',
     138                'TZS', 'UAH', 'UGX', 'USD', 'UYU', 'UZS', 'VEF', 'WST', 'XCD', 'YER', 'ZAR', 'ZMW',
     139            ),
     140            1000 => array( 'BHD', 'IQD', 'KWD', 'LYD', 'OMR', 'TND' ),
     141        );
     142
     143        foreach ( $currency_multipliers as $multiplier => $currencies ) {
     144            if ( in_array( $order_currency, $currencies, true ) ) {
     145                $match = $multiplier;
     146            }
     147        }
     148
     149        if ( is_null( $match ) ) {
     150            throw new Exception( "Unknown currency multiplier for $order_currency." );
     151        }
     152
     153        return $match;
     154    }
    73155}
Note: See TracChangeset for help on using the changeset viewer.