'paymentToken', 'payment_method_id' => 'paymentMethodId', 'client_ip' => 'clientIp', 'merchant_customer_id' => 'merchantCustomerId', ]; /** * @dataProvider validDataProvider * * @param mixed $options */ public function testSerialize(mixed $options): void { $serializer = new CreatePaymentRequestSerializer(); $instance = CreatePaymentRequest::builder()->build($options); $data = $serializer->serialize($instance); $expected = [ 'amount' => $options['amount'], ]; foreach ($this->fieldMap as $mapped => $field) { if (isset($options[$field])) { $value = $options[$field]; if (!empty($value)) { $expected[$mapped] = $value instanceof DateTime ? $value->format(YOOKASSA_DATE) : $value; } } } if (!empty($options['accountId']) && !empty($options['gatewayId'])) { $expected['recipient'] = [ 'gateway_id' => $options['gatewayId'], ]; } if (!empty($options['confirmation'])) { $expected['confirmation'] = [ 'type' => $options['confirmation']->getType(), ]; if ($locale = $options['confirmation']->getLocale()) { $expected['confirmation']['locale'] = $locale; } if (ConfirmationType::REDIRECT === $options['confirmation']->getType()) { $expected['confirmation']['enforce'] = $options['confirmation']->enforce; $expected['confirmation']['return_url'] = $options['confirmation']->returnUrl; } if (ConfirmationType::MOBILE_APPLICATION === $options['confirmation']->getType()) { $expected['confirmation']['return_url'] = $options['confirmation']->returnUrl; } } if (!empty($options['paymentMethodData'])) { $expected['payment_method_data'] = [ 'type' => $options['paymentMethodData']->getType(), ]; switch ($options['paymentMethodData']['type']) { case PaymentMethodType::ALFABANK: $expected['payment_method_data']['login'] = $options['paymentMethodData']->getLogin(); break; case PaymentMethodType::APPLE_PAY: $expected['payment_method_data']['payment_data'] = $options['paymentMethodData']->getPaymentData(); break; case PaymentMethodType::GOOGLE_PAY: $expected['payment_method_data']['payment_method_token'] = $options['paymentMethodData']->getPaymentMethodToken(); $expected['payment_method_data']['google_transaction_id'] = $options['paymentMethodData']->getGoogleTransactionId(); break; case PaymentMethodType::BANK_CARD: $expected['payment_method_data']['card'] = [ 'number' => $options['paymentMethodData']->getCard()->getNumber(), 'expiry_year' => $options['paymentMethodData']->getCard()->getExpiryYear(), 'expiry_month' => $options['paymentMethodData']->getCard()->getExpiryMonth(), 'csc' => $options['paymentMethodData']->getCard()->getCsc(), 'cardholder' => $options['paymentMethodData']->getCard()->getCardholder(), ]; break; case PaymentMethodType::MOBILE_BALANCE: case PaymentMethodType::CASH: case PaymentMethodType::SBERBANK: case PaymentMethodType::QIWI: $expected['payment_method_data']['phone'] = $options['paymentMethodData']->getPhone(); break; case PaymentMethodType::B2B_SBERBANK: /** @var PaymentDataB2bSberbank $paymentMethodData */ $paymentMethodData = $options['paymentMethodData']; $expected['payment_method_data']['payment_purpose'] = $paymentMethodData->getPaymentPurpose(); $expected['payment_method_data']['vat_data'] = $paymentMethodData->getVatData()->toArray(); break; } } if (!empty($options['metadata'])) { $expected['metadata'] = []; foreach ($options['metadata'] as $key => $value) { $expected['metadata'][$key] = $value; } } if (!empty($options['receipt']['items'])) { $expected['receipt'] = ['items' => []]; foreach ($options['receipt']['items'] as $item) { $itemArray = $item; if (!empty($item['payment_subject'])) { $itemArray['payment_subject'] = $item['payment_subject']; } if (!empty($item['payment_mode'])) { $itemArray['payment_mode'] = $item['payment_mode']; } if (!empty($item['payment_subject_industry_details'])) { $itemArray['payment_subject_industry_details'] = $item['payment_subject_industry_details']; } $expected['receipt']['items'][] = $itemArray; } if (!empty($options['receipt']['customer'])) { $expected['receipt']['customer'] = $options['receipt']['customer']; } if (!empty($options['receipt']['tax_system_code'])) { $expected['receipt']['tax_system_code'] = $options['receipt']['tax_system_code']; } if (!empty($options['receipt']['send'])) { $expected['receipt']['send'] = $options['receipt']['send']; } } if (array_key_exists('capture', $options)) { $expected['capture'] = (bool) $options['capture']; } if (array_key_exists('savePaymentMethod', $options) && isset($options['savePaymentMethod'])) { $expected['save_payment_method'] = (bool) $options['savePaymentMethod']; } if (!empty($options['description'])) { $expected['description'] = $options['description']; } if (!empty($options['airline'])) { $expected['airline'] = [ 'booking_reference' => $options['airline']['booking_reference'], 'ticket_number' => $options['airline']['ticket_number'], 'passengers' => array_map(static function ($passenger) { return [ 'first_name' => $passenger['first_name'], 'last_name' => $passenger['last_name'], ]; }, $options['airline']['passengers']), 'legs' => array_map(static function ($leg) { return [ 'departure_airport' => $leg['departure_airport'], 'destination_airport' => $leg['destination_airport'], 'departure_date' => $leg['departure_date'] instanceof DateTime ? $leg['departure_date']->format(Leg::ISO8601) : $leg['departure_date'], ]; }, $options['airline']['legs']), ]; } if (!empty($options['transfers'])) { $expected['transfers'] = []; foreach ($options['transfers'] as $item) { $itemArray = $item; if (!empty($item['account_id'])) { $itemArray['account_id'] = $item['account_id']; } if (!empty($item['amount'])) { $itemArray['amount'] = $item['amount']; } if (!empty($item['status'])) { $itemArray['status'] = $item['status']; } if (!empty($item['platform_fee_amount'])) { $itemArray['platform_fee_amount'] = $item['platform_fee_amount']; } if (!empty($item['description'])) { $itemArray['description'] = $item['description']; } if (!empty($item['metadata'])) { $itemArray['metadata'] = $item['metadata']; } $expected['transfers'][] = $itemArray; } } if (!empty($options['deal'])) { $expected['deal'] = $options['deal']; } if (!empty($options['pos_link'])) { $expected['pos_link'] = $options['pos_link']; } if (!empty($options['merchant_customer_id'])) { $expected['merchant_customer_id'] = $options['merchant_customer_id']; } self::assertEquals($expected, $data); } /** * @throws Exception */ public function validDataProvider(): array { $airline = new Airline(); $airline->setBookingReference(Random::str(10)); $airline->setTicketNumber(Random::int(10)); $leg = new Leg(); $leg->setDepartureAirport(Random::str(3, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')); $leg->setDestinationAirport(Random::str(3, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')); $leg->setDepartureDate('2018-12-31'); $airline->setLegs([$leg]); $passenger = new Passenger(); $passenger->setFirstName(Random::str(10)); $passenger->setLastName(Random::str(10)); $airline->setPassengers([$passenger]); $amount = Random::float(10, 999); $result = [ [ [ 'amount' => [ 'value' => sprintf('%.2f', round($amount, 2)), 'currency' => Random::value(CurrencyCode::getValidValues()), ], 'paymentToken' => Random::str(36), 'receipt' => [ 'items' => [ [ 'description' => Random::str(10), 'quantity' => (float) Random::int(1, 10), 'amount' => [ 'value' => (float) Random::int(100, 100), 'currency' => CurrencyCode::RUB, ], 'vat_code' => Random::int(1, 6), 'payment_subject' => PaymentSubject::COMMODITY, 'payment_mode' => PaymentMode::PARTIAL_PREPAYMENT, 'payment_subject_industry_details' => [ [ 'federal_id' => '001', 'document_date' => date('Y-m-d', Random::int(100000000, 200000000)), 'document_number' => Random::str(1, IndustryDetails::DOCUMENT_NUMBER_MAX_LENGTH), 'value' => Random::str(1, IndustryDetails::VALUE_MAX_LENGTH), ] ] ], ], 'customer' => [ 'email' => 'johndoe@yoomoney.ru', ], 'tax_system_code' => Random::int(1, 6), 'send' => true, ], 'description' => Random::str(10), 'capture' => true, 'savePaymentMethod' => null, 'airline' => [ 'booking_reference' => Random::str(10), 'ticket_number' => Random::int(10), 'passengers' => [ [ 'first_name' => Random::str(10, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'last_name' => Random::str(10, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), ], ], 'legs' => [ [ 'departure_airport' => Random::str(3, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'destination_airport' => Random::str(3, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'departure_date' => '2020-01-01', ], ], ], 'transfers' => [ [ 'account_id' => (string) Random::int(11111111, 99999999), 'amount' => [ 'value' => sprintf('%.2f', round($amount, 2)), 'currency' => Random::value(CurrencyCode::getValidValues()), ], 'status' => Random::value(TransferStatus::getValidValues()), 'platform_fee_amount' => [ 'value' => sprintf('%.2f', round(Random::float(0.1, 99.99), 2)), 'currency' => Random::value(CurrencyCode::getValidValues()), ], 'description' => Random::str(1, Transfer::MAX_LENGTH_DESCRIPTION), 'metadata' => ['test' => Random::str(10, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')], 'release_funds' => Random::bool(), ], ], 'deal' => [ 'id' => Random::str(36, 50), 'settlements' => [ [ 'type' => Random::value(SettlementPayoutPaymentType::getValidValues()), 'amount' => [ 'value' => sprintf('%.2f', round(Random::float(0.1, 99.99), 2)), 'currency' => Random::value(CurrencyCode::getValidValues()), ], ] ], ], 'merchant_customer_id' => Random::str(36, Payment::MAX_LENGTH_MERCHANT_CUSTOMER_ID), 'pos_link' => [ 'id' => Random::str(36, 36, '0123456789abcdef'), 'expires_at' => date(YOOKASSA_DATE), ], ], ], ]; $confirmations = [ new ConfirmationAttributesExternal(), new ConfirmationAttributesRedirect(), new ConfirmationAttributesMobileApplication(), ]; $paymentData = [ new PaymentDataSbp(), new PaymentDataApplePay(), new PaymentDataGooglePay(), new PaymentDataBankCard(), new PaymentDataMobileBalance(['phone' => Random::str(11, '0123456789')]), new PaymentDataQiwi(['phone' => Random::str(11, '0123456789')]), new PaymentDataSberbank(['phone' => Random::str(11, '0123456789')]), new PaymentDataCash(['phone' => Random::str(11, '0123456789')]), new PaymentDataYooMoney(), new PaymentDataInstallments(), new PaymentDataB2bSberbank(['payment_purpose' => Random::str(16), 'vat_data' => ['type' => VatDataType::UNTAXED]]), ]; $paymentData[1]->setPaymentData(Random::str(10)); $paymentData[2]->setPaymentMethodToken(Random::str(10)); $paymentData[2]->setGoogleTransactionId(Random::str(10)); $card = new PaymentDataBankCardCard(); $card->setNumber(Random::str(16, '0123456789')); $card->setExpiryYear(Random::int(2000, 2200)); $card->setExpiryMonth(Random::value(['01', '02', '03', '04', '05', '06', '07', '08', '09', '11', '12'])); $card->setCsc(Random::str(4, '0123456789')); $card->setCardholder(Random::str(26, 'abcdefghijklmnopqrstuvwxyz')); $paymentData[3]->setCard($card); $paymentData[4]->setPhone(Random::str(14, '0123456789')); $paymentData[6]->setPhone(Random::str(14, '0123456789')); /** @var PaymentDataB2bSberbank $paymentData [10] */ $paymentDataB2bSberbank = new PaymentDataB2bSberbank(); $paymentDataB2bSberbank->setPaymentPurpose(Random::str(10)); $paymentDataB2bSberbank->setVatData([ 'type' => VatDataType::CALCULATED, 'rate' => VatDataRate::RATE_10, 'amount' => [ 'value' => Random::int(1, 10000), 'currency' => CurrencyCode::USD, ], ]); $paymentData[10] = $paymentDataB2bSberbank; $confirmations[0]->setLocale('en_US'); $confirmations[1]->setEnforce(true); $confirmations[1]->setReturnUrl('https://test.com'); $confirmations[2]->setReturnUrl('https://test.ru'); foreach ($paymentData as $i => $paymentMethodData) { $request = [ 'accountId' => uniqid('', true), 'gatewayId' => uniqid('', true), 'amount' => [ 'value' => sprintf('%.2f', round($amount, 2)), 'currency' => Random::value(CurrencyCode::getValidValues()), ], 'referenceId' => uniqid('', true), 'paymentMethodData' => $paymentData[$i], 'confirmation' => Random::value($confirmations), 'savePaymentMethod' => Random::bool(), 'capture' => (bool)Random::int(0, 1), 'clientIp' => long2ip(Random::int(0, 2 ** 32)), 'metadata' => ['test' => uniqid('', true)], 'receipt' => [ 'items' => $this->getReceiptItem($i + 1), 'customer' => [ 'email' => 'johndoe@yoomoney.ru', 'phone' => Random::str(12, '0123456789'), ], 'tax_system_code' => Random::int(1, 6), 'send' => true, ], 'airline' => $airline->toArray(), 'deal' => [ 'id' => Random::str(36, 50), 'settlements' => [ [ 'type' => Random::value(SettlementPayoutPaymentType::getValidValues()), 'amount' => [ 'value' => sprintf('%.2f', round(Random::float(0.1, 99.99), 2)), 'currency' => Random::value(CurrencyCode::getValidValues()), ], ] ], ], 'merchant_customer_id' => Random::str(36, Payment::MAX_LENGTH_MERCHANT_CUSTOMER_ID), 'pos_link' => [ 'id' => Random::str(36, 36, '0123456789abcdef'), 'expires_at' => date(YOOKASSA_DATE), ], ]; $result[] = [$request]; } return $result; } /** * @param mixed $count * * @return array */ private function getReceiptItem(mixed $count): array { $result = []; for ($i = 0; $i < $count; $i++) { $result[] = [ 'description' => Random::str(10), 'quantity' => (float) Random::float(1, 100), 'amount' => [ 'value' => (float) Random::int(1, 100), 'currency' => CurrencyCode::RUB, ], 'vat_code' => Random::int(1, 6), 'payment_subject' => PaymentSubject::COMMODITY, 'payment_mode' => PaymentMode::PARTIAL_PREPAYMENT, 'payment_subject_industry_details' => [ [ 'federal_id' => '001', 'document_date' => date('Y-m-d', Random::int(100000000, 200000000)), 'document_number' => Random::str(1, IndustryDetails::DOCUMENT_NUMBER_MAX_LENGTH), 'value' => Random::str(1, IndustryDetails::VALUE_MAX_LENGTH), ] ] ]; } return $result; } }