287 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			287 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace Faker\Provider;
 | 
						|
 | 
						|
use Faker\Calculator\Iban;
 | 
						|
use Faker\Calculator\Luhn;
 | 
						|
 | 
						|
class Payment extends Base
 | 
						|
{
 | 
						|
    public static $expirationDateFormat = "m/y";
 | 
						|
 | 
						|
    protected static $cardVendors = array(
 | 
						|
        'Visa', 'Visa', 'Visa', 'Visa', 'Visa',
 | 
						|
        'MasterCard', 'MasterCard', 'MasterCard', 'MasterCard', 'MasterCard',
 | 
						|
        'American Express', 'Discover Card', 'Visa Retired'
 | 
						|
    );
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var array List of card brand masks for generating valid credit card numbers
 | 
						|
     * @see https://en.wikipedia.org/wiki/Payment_card_number Reference for existing prefixes
 | 
						|
     * @see https://www.mastercard.us/en-us/issuers/get-support/2-series-bin-expansion.html MasterCard 2017 2-Series BIN Expansion
 | 
						|
     */
 | 
						|
    protected static $cardParams = array(
 | 
						|
        'Visa' => array(
 | 
						|
            "4539###########",
 | 
						|
            "4556###########",
 | 
						|
            "4916###########",
 | 
						|
            "4532###########",
 | 
						|
            "4929###########",
 | 
						|
            "40240071#######",
 | 
						|
            "4485###########",
 | 
						|
            "4716###########",
 | 
						|
            "4##############"
 | 
						|
        ),
 | 
						|
        'Visa Retired' => array(
 | 
						|
            "4539########",
 | 
						|
            "4556########",
 | 
						|
            "4916########",
 | 
						|
            "4532########",
 | 
						|
            "4929########",
 | 
						|
            "40240071####",
 | 
						|
            "4485########",
 | 
						|
            "4716########",
 | 
						|
            "4###########",
 | 
						|
        ),
 | 
						|
        'MasterCard' => array(
 | 
						|
            "2221###########",
 | 
						|
            "23#############",
 | 
						|
            "24#############",
 | 
						|
            "25#############",
 | 
						|
            "26#############",
 | 
						|
            "2720###########",
 | 
						|
            "51#############",
 | 
						|
            "52#############",
 | 
						|
            "53#############",
 | 
						|
            "54#############",
 | 
						|
            "55#############"
 | 
						|
        ),
 | 
						|
        'American Express' => array(
 | 
						|
            "34############",
 | 
						|
            "37############"
 | 
						|
        ),
 | 
						|
        'Discover Card' => array(
 | 
						|
            "6011###########"
 | 
						|
        ),
 | 
						|
    );
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var array list of IBAN formats, source: @link https://www.swift.com/standards/data-standards/iban
 | 
						|
     */
 | 
						|
    protected static $ibanFormats = array(
 | 
						|
        'AD' => array(array('n', 4),    array('n', 4),  array('c', 12)),
 | 
						|
        'AE' => array(array('n', 3),    array('n', 16)),
 | 
						|
        'AL' => array(array('n', 8),    array('c', 16)),
 | 
						|
        'AT' => array(array('n', 5),    array('n', 11)),
 | 
						|
        'AZ' => array(array('a', 4),    array('c', 20)),
 | 
						|
        'BA' => array(array('n', 3),    array('n', 3),  array('n', 8),  array('n', 2)),
 | 
						|
        'BE' => array(array('n', 3),    array('n', 7),  array('n', 2)),
 | 
						|
        'BG' => array(array('a', 4),    array('n', 4),  array('n', 2),  array('c', 8)),
 | 
						|
        'BH' => array(array('a', 4),    array('c', 14)),
 | 
						|
        'BR' => array(array('n', 8),    array('n', 5),  array('n', 10), array('a', 1),  array('c', 1)),
 | 
						|
        'CH' => array(array('n', 5),    array('c', 12)),
 | 
						|
        'CR' => array(array('n', 3),    array('n', 14)),
 | 
						|
        'CY' => array(array('n', 3),    array('n', 5),  array('c', 16)),
 | 
						|
        'CZ' => array(array('n', 4),    array('n', 6),  array('n', 10)),
 | 
						|
        'DE' => array(array('n', 8),    array('n', 10)),
 | 
						|
        'DK' => array(array('n', 4),    array('n', 9),  array('n', 1)),
 | 
						|
        'DO' => array(array('c', 4),    array('n', 20)),
 | 
						|
        'EE' => array(array('n', 2),    array('n', 2),  array('n', 11), array('n', 1)),
 | 
						|
        'ES' => array(array('n', 4),    array('n', 4),  array('n', 1),  array('n', 1),  array('n', 10)),
 | 
						|
        'FI' => array(array('n', 6),    array('n', 7),  array('n', 1)),
 | 
						|
        'FR' => array(array('n', 5),    array('n', 5),  array('c', 11), array('n', 2)),
 | 
						|
        'GB' => array(array('a', 4),    array('n', 6),  array('n', 8)),
 | 
						|
        'GE' => array(array('a', 2),    array('n', 16)),
 | 
						|
        'GI' => array(array('a', 4),    array('c', 15)),
 | 
						|
        'GR' => array(array('n', 3),    array('n', 4),  array('c', 16)),
 | 
						|
        'GT' => array(array('c', 4),    array('c', 20)),
 | 
						|
        'HR' => array(array('n', 7),    array('n', 10)),
 | 
						|
        'HU' => array(array('n', 3),    array('n', 4),  array('n', 1),  array('n', 15), array('n', 1)),
 | 
						|
        'IE' => array(array('a', 4),    array('n', 6),  array('n', 8)),
 | 
						|
        'IL' => array(array('n', 3),    array('n', 3),  array('n', 13)),
 | 
						|
        'IS' => array(array('n', 4),    array('n', 2),  array('n', 6),  array('n', 10)),
 | 
						|
        'IT' => array(array('a', 1),    array('n', 5),  array('n', 5),  array('c', 12)),
 | 
						|
        'KW' => array(array('a', 4),    array('n', 22)),
 | 
						|
        'KZ' => array(array('n', 3),    array('c', 13)),
 | 
						|
        'LB' => array(array('n', 4),    array('c', 20)),
 | 
						|
        'LI' => array(array('n', 5),    array('c', 12)),
 | 
						|
        'LT' => array(array('n', 5),    array('n', 11)),
 | 
						|
        'LU' => array(array('n', 3),    array('c', 13)),
 | 
						|
        'LV' => array(array('a', 4),    array('c', 13)),
 | 
						|
        'MC' => array(array('n', 5),    array('n', 5),  array('c', 11), array('n', 2)),
 | 
						|
        'MD' => array(array('c', 2),    array('c', 18)),
 | 
						|
        'ME' => array(array('n', 3),    array('n', 13), array('n', 2)),
 | 
						|
        'MK' => array(array('n', 3),    array('c', 10), array('n', 2)),
 | 
						|
        'MR' => array(array('n', 5),    array('n', 5),  array('n', 11), array('n', 2)),
 | 
						|
        'MT' => array(array('a', 4),    array('n', 5),  array('c', 18)),
 | 
						|
        'MU' => array(array('a', 4),    array('n', 2),  array('n', 2),  array('n', 12), array('n', 3),  array('a', 3)),
 | 
						|
        'NL' => array(array('a', 4),    array('n', 10)),
 | 
						|
        'NO' => array(array('n', 4),    array('n', 6),  array('n', 1)),
 | 
						|
        'PK' => array(array('a', 4),    array('c', 16)),
 | 
						|
        'PL' => array(array('n', 8),    array('n', 16)),
 | 
						|
        'PS' => array(array('a', 4),    array('c', 21)),
 | 
						|
        'PT' => array(array('n', 4),    array('n', 4),  array('n', 11), array('n', 2)),
 | 
						|
        'RO' => array(array('a', 4),    array('c', 16)),
 | 
						|
        'RS' => array(array('n', 3),    array('n', 13), array('n', 2)),
 | 
						|
        'SA' => array(array('n', 2),    array('c', 18)),
 | 
						|
        'SE' => array(array('n', 3),    array('n', 16), array('n', 1)),
 | 
						|
        'SI' => array(array('n', 5),    array('n', 8),  array('n', 2)),
 | 
						|
        'SK' => array(array('n', 4),    array('n', 6),  array('n', 10)),
 | 
						|
        'SM' => array(array('a', 1),    array('n', 5),  array('n', 5),  array('c', 12)),
 | 
						|
        'TN' => array(array('n', 2),    array('n', 3),  array('n', 13), array('n', 2)),
 | 
						|
        'TR' => array(array('n', 5),    array('n', 1),  array('c', 16)),
 | 
						|
        'VG' => array(array('a', 4),    array('n', 16)),
 | 
						|
    );
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return string Returns a credit card vendor name
 | 
						|
     *
 | 
						|
     * @example 'MasterCard'
 | 
						|
     */
 | 
						|
    public static function creditCardType()
 | 
						|
    {
 | 
						|
        return static::randomElement(static::$cardVendors);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the String of a credit card number.
 | 
						|
     *
 | 
						|
     * @param string  $type      Supporting any of 'Visa', 'MasterCard', 'American Express', and 'Discover'
 | 
						|
     * @param boolean $formatted Set to true if the output string should contain one separator every 4 digits
 | 
						|
     * @param string  $separator Separator string for formatting card number. Defaults to dash (-).
 | 
						|
     * @return string
 | 
						|
     *
 | 
						|
     * @example '4485480221084675'
 | 
						|
     */
 | 
						|
    public static function creditCardNumber($type = null, $formatted = false, $separator = '-')
 | 
						|
    {
 | 
						|
        if (is_null($type)) {
 | 
						|
            $type = static::creditCardType();
 | 
						|
        }
 | 
						|
        $mask = static::randomElement(static::$cardParams[$type]);
 | 
						|
 | 
						|
        $number = static::numerify($mask);
 | 
						|
        $number .= Luhn::computeCheckDigit($number);
 | 
						|
 | 
						|
        if ($formatted) {
 | 
						|
            $p1 = substr($number, 0, 4);
 | 
						|
            $p2 = substr($number, 4, 4);
 | 
						|
            $p3 = substr($number, 8, 4);
 | 
						|
            $p4 = substr($number, 12);
 | 
						|
            $number = $p1 . $separator . $p2 . $separator . $p3 . $separator . $p4;
 | 
						|
        }
 | 
						|
 | 
						|
        return $number;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param boolean $valid True (by default) to get a valid expiration date, false to get a maybe valid date
 | 
						|
     * @return \DateTime
 | 
						|
     * @example 04/13
 | 
						|
     */
 | 
						|
    public function creditCardExpirationDate($valid = true)
 | 
						|
    {
 | 
						|
        if ($valid) {
 | 
						|
            return $this->generator->dateTimeBetween('now', '36 months');
 | 
						|
        }
 | 
						|
 | 
						|
        return $this->generator->dateTimeBetween('-36 months', '36 months');
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param boolean $valid                True (by default) to get a valid expiration date, false to get a maybe valid date
 | 
						|
     * @param string  $expirationDateFormat
 | 
						|
     * @return string
 | 
						|
     * @example '04/13'
 | 
						|
     */
 | 
						|
    public function creditCardExpirationDateString($valid = true, $expirationDateFormat = null)
 | 
						|
    {
 | 
						|
        return $this->creditCardExpirationDate($valid)->format(is_null($expirationDateFormat) ? static::$expirationDateFormat : $expirationDateFormat);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param  boolean $valid True (by default) to get a valid expiration date, false to get a maybe valid date
 | 
						|
     * @return array
 | 
						|
     */
 | 
						|
    public function creditCardDetails($valid = true)
 | 
						|
    {
 | 
						|
        $type = static::creditCardType();
 | 
						|
 | 
						|
        return array(
 | 
						|
            'type'   => $type,
 | 
						|
            'number' => static::creditCardNumber($type),
 | 
						|
            'name'   => $this->generator->name(),
 | 
						|
            'expirationDate' => $this->creditCardExpirationDateString($valid)
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * International Bank Account Number (IBAN)
 | 
						|
     *
 | 
						|
     * @link http://en.wikipedia.org/wiki/International_Bank_Account_Number
 | 
						|
     * @param  string  $countryCode ISO 3166-1 alpha-2 country code
 | 
						|
     * @param  string  $prefix      for generating bank account number of a specific bank
 | 
						|
     * @param  integer $length      total length without country code and 2 check digits
 | 
						|
     * @return string
 | 
						|
     */
 | 
						|
    public static function iban($countryCode = null, $prefix = '', $length = null)
 | 
						|
    {
 | 
						|
        $countryCode = is_null($countryCode) ? self::randomKey(self::$ibanFormats) : strtoupper($countryCode);
 | 
						|
 | 
						|
        $format = !isset(static::$ibanFormats[$countryCode]) ? null : static::$ibanFormats[$countryCode];
 | 
						|
        if ($length === null) {
 | 
						|
            if ($format === null) {
 | 
						|
                $length = 24;
 | 
						|
            } else {
 | 
						|
                $length = 0;
 | 
						|
                foreach ($format as $part) {
 | 
						|
                    list($class, $groupCount) = $part;
 | 
						|
                    $length += $groupCount;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        if ($format === null) {
 | 
						|
            $format = array(array('n', $length));
 | 
						|
        }
 | 
						|
 | 
						|
        $expandedFormat = '';
 | 
						|
        foreach ($format as $item) {
 | 
						|
            list($class, $length) = $item;
 | 
						|
            $expandedFormat .=  str_repeat($class, $length);
 | 
						|
        }
 | 
						|
 | 
						|
        $result = $prefix;
 | 
						|
        $expandedFormat = substr($expandedFormat, strlen($result));
 | 
						|
        foreach (str_split($expandedFormat) as $class) {
 | 
						|
            switch ($class) {
 | 
						|
                default:
 | 
						|
                case 'c':
 | 
						|
                    $result .= mt_rand(0, 100) <= 50 ? static::randomDigit() : strtoupper(static::randomLetter());
 | 
						|
                    break;
 | 
						|
                case 'a':
 | 
						|
                    $result .= strtoupper(static::randomLetter());
 | 
						|
                    break;
 | 
						|
                case 'n':
 | 
						|
                    $result .= static::randomDigit();
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        $checksum = Iban::checksum($countryCode . '00' . $result);
 | 
						|
 | 
						|
        return $countryCode . $checksum . $result;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the String of a SWIFT/BIC number
 | 
						|
     *
 | 
						|
     * @example 'RZTIAT22263'
 | 
						|
     * @link    http://en.wikipedia.org/wiki/ISO_9362
 | 
						|
     * @return  string Swift/Bic number
 | 
						|
     */
 | 
						|
    public static function swiftBicNumber()
 | 
						|
    {
 | 
						|
        return self::regexify("^([A-Z]){4}([A-Z]){2}([0-9A-Z]){2}([0-9A-Z]{3})?$");
 | 
						|
    }
 | 
						|
}
 |