Last active
November 15, 2023 12:20
-
-
Save BBGuy/c362a30bb0dda65777b076040b14cab5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// some examples on | |
// https://docs.drupalcommerce.org/commerce2/developer-guide/products/product-architecture/code-recipes | |
// https://docs.drupalcommerce.org/commerce2/developer-guide/products/product-management/code-recipes | |
// https://docs.drupalcommerce.org/commerce2/developer-guide/products/displaying-products/code-recipes | |
// Work with orders. | |
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */ | |
$order = \Drupal::entityTypeManager()->getStorage('commerce_order')->load($order_id); | |
$order_id = $order->id(); | |
// Work with line items. | |
$qty = $order_item->getQuantity(); | |
// Work with products | |
// Load the product mathod 1. | |
$product = \Drupal\commerce_product\Entity\Product::load($prod_id); | |
// Load the product mathod 2. | |
$entity = \Drupal::entityTypeManager()->getStorage('commerce_product')->load($prod_id); | |
// Load the product mathod 3. | |
$entity = \Drupal::service('entity_type.manager')->getStorage('commerce_product')->load($prod_id); | |
// Check the status | |
$is_published = $product->isPublished(); | |
// Get the Product Variation ID from the product. | |
$variation_id = $product->getVariationIds()[0]; | |
// Get the Product Variation from the product. | |
$variation = $product->getDefaultVariation(); | |
// Load the product variation. | |
$variation_storage = \Drupal::service('entity_type.manager')->getStorage('commerce_product_variation'); | |
$product_variation = $variation_storage->load($variation_id); | |
$variation_id = $product_variation->id(); | |
// Get the product form the variation | |
$product = $product_variation->getProduct(); | |
$product_id = $product_variation->getProductId(); | |
// Reading price from an entity \Drupal\Core\Entity\EntityInterface $entity (not using purchasable entity) | |
$number = $entity->price->number; | |
$curreny = $entity->price->currency_code; | |
$price_break_1 = $entity->field_price_break_1->number; | |
$price_break_1 = $entity->field_price_break_2->number; | |
// Cycle the line items of an order and load each product. | |
foreach ($order->getItems() as $id => $order_item) { | |
$purchased_entity = $order_item->getPurchasedEntity(); | |
$pe_price = $purchased_entity->getPrice(); | |
if (!$purchased_entity) { | |
// Not every order item has a purchased entity. | |
continue; | |
} | |
$name = $purchased_entity->getTitle(); | |
$qty = $order_item->getQuantity(); | |
// Unit price | |
$unit_price_obj = $order_item->getUnitPrice(); | |
$price_amount = $unit_price_obj->getNumber(); | |
$price_currency = $unit_price_obj->getCurrencyCode(); | |
// Line total price | |
$line_price_obj = $order_item->getTotalPrice(); | |
} | |
// Set the price example 1 | |
$new_price = new Price('12.36', 'GBP'); | |
$variation->set('price', $new_price); | |
$variation->save(); | |
// Set the price example 2 | |
/** @var \Drupal\commerce_product\ProductVariationStorageInterface $variation_storage */ | |
$variation_storage = \Drupal::service('entity_type.manager')->getStorage('commerce_product_variation'); | |
/** @var \Drupal\commerce_product\Entity\ProductVariationInterface|null */ | |
$variation = $variation_storage->loadBySku($part_number); | |
if (isset($variation)) { | |
$price_obj = $variation->getPrice(); | |
$price_currency = $price_obj->getCurrencyCode(); | |
$new_price = new Price('12.36', $price_currency); | |
$variation->set('price', $new_price); | |
$variation->save(); | |
} | |
// Conver currency (convert order sub total price to pounds for comparicen) | |
$order_total = $order->getSubtotalPrice(); | |
// Make sure we are using £. | |
$order_total_amount_gbp = \Drupal::service('commerce_currency_resolver.calculator')->priceConversion($order_total, 'GBP'); | |
$order_total_amount = (float) $order_total_amount_gbp->getNumber(); | |
if ($order_total_amount < 175) { | |
// Do somthing. | |
} | |
// Needs the following use at the top of the file: | |
// use Drupal\commerce_product\Entity\ProductVariationInterface; | |
// Check if a purchasable entity is a product variation. | |
if ($purchasable_entity instanceof ProductVariationInterface) { | |
// Get the product variation from a line item. | |
$product_variation = $line_item->getPurchasedEntity(); | |
} | |
// Get the Cart provider service | |
$cart_provider = \Drupal::service('commerce_cart.cart_provider'); | |
// Get all the carts. | |
$all_carts = \Drupal::service('commerce_cart.cart_provider')->getCarts(); | |
// Get the current store. | |
$store = \Drupal::service('commerce_store.current_store')->getStore(); | |
// Get the cart for the curent store. | |
$cart = \Drupal::service('commerce_cart.cart_provider')->getCart('default', $store); | |
// get the store from an order | |
$order->getStore(); | |
$order->getStoreid(); | |
// Add to cart form | |
// Get the add to cart entity form. | |
$entity_form = $form_state->getFormObject(); | |
// Get the line item and $purchased_entity. | |
$order_item = $entity_form->getEntity(); | |
/** @var \Drupal\commerce\PurchasableEntityInterface $purchased_entity */ | |
$purchased_entity = $order_item->getPurchasedEntity(); | |
// Get the $context from the Add to cart form | |
/** @var \Drupal\commerce_product\Entity\ProductInterface $product */ | |
$product = $form_state->get('product'); | |
$selected_variation_id = $form_state->get('selected_variation'); | |
if (!empty($selected_variation_id)) { | |
$selected_variation = \Drupal\commerce_product\Entity\ProductVariation::load($selected_variation_id); | |
} | |
else { | |
$selected_variation = $product->getDefaultVariation(); | |
} | |
$context = commerce_stock_enforcement_get_context($selected_variation); | |
// Working with the cart page | |
// Get the order from the form state. | |
$order = $form_state->getFormObject()->getEntity(); | |
// Checkout | |
// Check if the checkout form. need to make sure its not the commerce_checkout_flow_form (used to create new checkout flows) | |
if (strpos($form_id, "commerce_checkout_flow") !== false && $form_state->getFormObject()->getBaseFormId() == 'commerce_checkout_flow') { | |
// Get the order from the form | |
/** @var Drupal\Core\Form\FormInterface $form_object */ | |
$form_object = $form_state->getFormObject(); | |
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */ | |
$order = $form_object->getOrder(); | |
// get a field value using getValue(), check it and cycle using the store. | |
$store = $context->getStore(); | |
$locations = $store->field_available_stock_locations->getValue(); | |
// If we have store locations. | |
if (!empty($locations)) { | |
// Load them. | |
$store_locations = []; | |
foreach ($locations as $location) { | |
$store_locations[$location['target_id']] = $location['target_id']; | |
} | |
$store_locations = $this->loadMultiple($store_locations); | |
} | |
// Check what type is a PurchasableEntity. | |
$entity_type = $entity->getEntityTypeId(); //example: commerce_product_variation | |
$entity_bundle = $entity->bundle(); //example: default | |
// Reading a field with a single value - all the below will return the same value | |
$external_product_id = $entity->field_external_product_id->getValue()[0]['value']; | |
$external_product_id = $entity->field_external_product_id->getString(); | |
$external_product_id = $entity->field_external_product_id->value; | |
$external_product_id = $entity->field_external_product_id[0]->value; | |
// User data | |
// Get details from the order | |
$billing_profile = $order->getBillingProfile(); | |
$email = $this->order->getEmail(); | |
$address = $billing_profile->address->first(); | |
$line_1 = $address->address_line1, | |
$line_2 = $address->address_line2, | |
$city = $address->locality, | |
$company = $address->organization, | |
$country = $address->country_code, | |
$first_name = $address->given_name, | |
$middle_name = $address->additional_name, | |
$last_name = $address->family_name, | |
$state = $address->administrative_area, | |
$post_code = $address->postal_code, | |
$custom_field $order->field_custom_field; | |
// Update order | |
$order->field_custom_field = 'custom value'; | |
$order->save(); | |
// Get Billing and shipping Profiles. | |
$profiles = $order->collectProfiles(); | |
if (isset($profiles['billing'])) { | |
$billing_profile = $profiles['billing']; | |
} | |
if (isset($profiles['shipping'])) { | |
$shipping_profile = $profiles['shipping']; | |
} | |
// Get address as an array | |
$billing_profile->get('address')->first()->toArray()) | |
// Check a profile type | |
$profile_type = $profile->type->target_id; | |
if ($profile_type == 'customer) { | |
// Customer profile code | |
} | |
// Shipping | |
// Get the shipments entity from the order reference. | |
$shipments = $order->shipments->referencedEntities(); | |
$shipments = $order->get('shipments')->referencedEntities(); | |
// Get the first shipment entity. | |
/** @var \Drupal\commerce_shipping\Entity\ShipmentInterface $shipment */ | |
$shipment = reset($shipments); | |
// Get shipping Profile | |
$shipping_profile = $shipment->getShippingProfile(); | |
// Get the address (from this point its the same as billing address) | |
$address = $shipping_profile->address->first(); | |
$line_1 $shipping_profile->get('address')->address_line1; | |
// Get the address book profile ID. | |
$address_book_profile_id = $shipping_profile->getData('address_book_profile_id'); | |
$address_book_profile = Profile::load($address_book_profile_id); | |
$is_default = $address_book_profile->isDefault(); | |
// Shipping Method info. | |
$shipping_method = $shipment->getShippingMethod(); | |
$shipping_method_label = $shipment->getShippingMethod()->label(); | |
$shipping_method_id = $shipment->getShippingMethodId(); | |
// Shipping service info. | |
$shipping_service = $shipment->getShippingService(); | |
// Amount. | |
$shipping_amount_obj = $shipment->getAmount(); | |
$shipping_original_amount_obj = $shipment->getOriginalAmount(); | |
$shipping_amount = $shipping_amount_obj->getNumber(); | |
$shipping_amount_currency =$shipping_amount_obj->getCurrencyCode() | |
// Other | |
$package_type = $shipment->getPackageType(); | |
$package_type = $shipment->getPackageType(); | |
$package_type_id = $shipment->getPackageType()->getId(); | |
// Order states - check for state change | |
$order_state = $order->getState(); | |
$new_state = $order_state->getLabel(); | |
$original_state = $order_state->getOriginalLabel(); | |
\Drupal::messenger()->addMessage(t('state changed from @from to @to.', ['@from' => $original_state, '@to' => $new_state])); | |
// Order Workflow | |
// Gets the workflow group i.e. commerce_order. | |
$workflow_id = $order->getState()->getWorkflow()->getId(); | |
// Get the workflow ID i.e. order_default, order_fulfillment .. | |
$workflow_group = $order->getState()->getWorkflow()->getGroup(); | |
// Check it is the base commerce_order workflow | |
if ($order->getState()->getWorkflow()->getGroup() !== 'commerce_order') { | |
return; | |
} | |
// Price adjustments | |
// full documentation: https://docs.drupalcommerce.org/commerce2/developer-guide/pricing/adjustments | |
/** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */ | |
$adjustment_amount = $order_item->getUnitPrice()->multiply(0.1); | |
$order_item->addAdjustment(new Adjustment([ | |
'type' => 'custom', | |
'label' => 'Plus 10%', | |
'amount' => $adjustment_amount, | |
'percentage' => '0.1', | |
'included' => FALSE, | |
'locked' => TRUE, | |
])); | |
$order_item->addAdjustment(new Adjustment([ | |
'type' => 'fee', | |
'label' => '$10 fee', | |
'amount' => new Price('10.00', 'USD'), | |
]); | |
// Read pricing information. | |
$order_item->getUnitPrice(); | |
$order_item->getTotalPrice(); | |
$order_item->getAdjustedTotalPrice(); | |
$order_item->getAdjustedTotalPrice(['custom']); | |
$order_item->getAdjustedTotalPrice(['fee']); | |
// Order adjustments | |
$order->addAdjustment(new Adjustment([ | |
'type' => 'fee', | |
'label' => 'Handling fee', | |
'amount' => new Price('10.00', 'USD'), | |
'locked' => TRUE, | |
])); | |
// Read pricing information. | |
$order->getTotalPrice(); | |
$order->getSubtotalPrice(); | |
$order->getAdjustments(); | |
$order->getAdjustments(['fee']) | |
// Split a $10 discount across all the lines of an order. | |
$splitter = \Drupal::getContainer()->get('commerce_order.price_splitter'); | |
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */ | |
$amounts = $splitter->split($order, new Price('10.00', 'USD')); | |
foreach ($order->getItems() as $order_item) { | |
if (isset($amounts[$order_item->id()])) { | |
$order_item->addAdjustment(new Adjustment([ | |
'type' => 'custom', | |
'label' => $this->t('Special'), | |
'amount' => $amounts[$order_item->id()]->multiply('-1'), | |
])); | |
} | |
} | |
// Calculate the total unit discount for a line: | |
$purchased_entity = $order_item->getPurchasedEntity(); | |
$purchased_entity_price = $purchased_entity->getPrice()->getNumber(); | |
$line_adjustmented_unit_price = $order_item->getAdjustedUnitPrice()->getNumber(); | |
$unit_discounbt = $purchased_entity_price - $line_adjustmented_unit_price; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
//** Stock Transactions **// | |
// Create a stock transaction | |
$stockManager = \Drupal::service('commerce_stock.service_manager'); | |
// High level typed transaction using the stock manager. | |
$stockManager->receiveStock($purchasable_entity, $location_id, $zone, $quantity, $unit_cost, $message); | |
// Low level un-typed transaction using the stock updater. | |
$stockManager->getService($purchasable_entity)->getStockUpdater()->createTransaction($purchasable_entity, $location_id, $zone, $quantity, $unit_cost, $transaction_type, $metadata); | |
//** Use Commerce Stock to check stock **// | |
// The easy way to check. | |
/** @var \Drupal\commerce_stock\StockServiceManagerInterface $stockManager */ | |
$stockManager = \Drupal::service('commerce_stock.service_manager'); | |
$stock = $stockManager->getStockLevel($variation); | |
// The long way. | |
//Get the Stock manager: | |
/** @var \Drupal\commerce_stock\StockServiceManagerInterface $stockManager */ | |
$stockManager = \Drupal::service('commerce_stock.service_manager'); | |
// Get the Stock service for the PurchasableEntity and use that to get the stock checker. | |
$stock_service = $stockManager->getService($variation); | |
$stock_checker = $stock_service->getStockChecker(); | |
// You can then check if it is always in stock: | |
$is_always_in_stock = $stock_checker->getIsAlwaysInStock($variation); | |
// Get the configuration object. Needed to get the locations to check for. | |
$stock_config = $stock_service->getConfiguration(); | |
// Get the context. | |
$context = commerce_stock_enforcement_get_context($variation); | |
// and finally you can get the stock level: | |
$stock_level = $stock_checker->getTotalStockLevel( | |
$variation, | |
$stock_config->getAvailabilityLocations($context, $variation) | |
); | |
//** Used Drupal Commerce to check stock **// | |
// Deprecated/does not work - Check if available using drupal commerce. | |
/** @var \Drupal\commerce\AvailabilityManager $availabilityManager */ | |
$availabilityManager = \Drupal::service('commerce.availability_manager'); | |
// Get the context. | |
$context = commerce_stock_enforcement_get_context($variation); | |
// Check | |
$availabe = $availabilityManager->check($variation, 1, $context); | |
// Not sure - New way to check with core drupal commerce | |
/** @var \Drupal\commerce_order\AvailabilityManager $availabilityManager */ | |
$availabilityManager = \Drupal::service('commerce.availability_manager'); | |
// Get the context. | |
$context = commerce_stock_enforcement_get_context($variation); | |
// Check | |
$order_item = @todo - get an item from the product. | |
$availabe = $availabilityManager->check($order_item, $context); | |
// Get Stock level | |
// Get the Stock service for the PurchasableEntity and use that to get the stock checker. | |
$stock_service = $stockManager->getService($entity); | |
$stock_checker = $stock_service->getStockChecker(); | |
// You can then check if it is always in stock: | |
stock_checker->getIsAlwaysInStock($entity) | |
// Get the configuration object. Needed to get the locations to check for. | |
// $stock_config = $stock_service->getConfiguration(); | |
// and finally you can get the stock level: | |
$stock_level = $stock_checker->getTotalStockLevel( | |
$entity, | |
$stock_config->getAvailabilityLocations($context, $entity) | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Delete a product and its variations. | |
function RemoveProduct($product_id) { | |
/** @var \Drupal\commerce_product\Entity\ProductInterface $product */ | |
$product = \Drupal\commerce_product\Entity\Product::load($product_id); | |
// Delete all product variations associated with the product (should be only one). | |
$variations = $product->getVariations(); | |
foreach ($variations as $variation) { | |
$variation->delete(); | |
} | |
// Delete the product | |
$product->delete(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Util functions for https://www.drupal.org/project/commerce_exchanger | |
// used for currency convertion. | |
/** @var \Drupal\commerce_exchanger\DefaultExchangerCalculator $exchanger_calculate */ | |
$exchanger_calculator = \Drupal::service('commerce_exchanger.calculate'); | |
// Conver unit price to GBP | |
$unit_price = $exchanger_calculator->priceConversion($unit_price, 'GBP'); | |
// Get the rates. | |
$rates = $exchanger_calculator->getExchangeRates(); | |
// Get the € to £ rate (make sure you check it is set before using) | |
$ex_rate = $rates['EUR']['GBP']['value']; | |
// Use commerce core functionality to convert the price. | |
$gbp_unit_price = $eur_unit_price->convert('GBP', $ex_rate); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Create a product and variation | |
public function createProduct(array $product) { | |
$sku = strtoupper($product['sku']); | |
$title = $product['title']; | |
// Create product variatin. | |
$variation = ProductVariation::create([ | |
'type' => 'default', | |
'sku' => $sku, | |
'status' => TRUE, | |
'price' => new Price('25.99', 'GBP'), | |
]); | |
$variation->save(); | |
$variations = [$variation]; | |
// Create the product | |
$product = Product::create([ | |
'type' => 'default', | |
'title' => $title, | |
'variations' => $variations, | |
]); | |
$product->save(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Payment method. | |
$payment_method = $order->get('payment_method')->entity; | |
// Payment method values. | |
$method_id = $payment_method->get('method_id')->value; | |
$payment_type = $payment_method->get('type')->value; | |
$card_type = $payment_method->get('card_type')->value; | |
// The remote ID returned by the request. | |
$remote_id = $payment_method->get('remote_id')->value; | |
// method + last two card digits. | |
$payment_method->label(); | |
// Detailed information not needed as includes billing information. | |
$view_builder = $this->entityTypeManager->getViewBuilder('commerce_payment_method'); | |
$payment_summary = $view_builder->view($payment_method, 'default'); | |
// Payment Gateway | |
$payment_gateway = $payment_method->get('payment_gateway')->referencedEntities()[0]; | |
$payment_gateway_mode = $payment_method->get('payment_gateway_mode')->value; | |
$payment_gateway_id = $payment_gateway->get('id'); | |
$payment_gateway_configuration = $payment_gateway->get('configuration'); | |
// Payment Gateway API Key | |
$api_key = $payment_gateway_configuration['api_key']; | |
// Get payment_method details for templating. | |
$payment_method = $order->get('payment_method')->entity; | |
if ($payment_method) { | |
// method + last two card digits. | |
$payment_summary = $payment_method->label(); | |
} | |
else { | |
/** @var \Drupal\commerce_payment\Entity\PaymentGatewayInterface $payment_gateway */ | |
$payment_gateway = $order->get('payment_gateway')->entity; | |
$payment_summary = [ | |
'payment_gateway' => [ | |
'#markup' => $payment_gateway->getPlugin()->getDisplayLabel(), | |
], | |
]; | |
} | |
$body['#payment_method'] = $payment_summary; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Also see examples in main Commerce 2.x code.php file. | |
// Create a price object | |
$price = new Price(10.50, 'GBP'); | |
// Display | |
/** @var \CommerceGuys\Intl\Formatter\CurrencyFormatterInterface $currency_formatter */ | |
$currency_formatter = \Drupal::service('commerce_price.currency_formatter'); | |
$formatted_price = $currency_formatter->format($price->getNumber(), $price->getCurrencyCode()); | |
// Convert from one currency to another. | |
/** @var \Drupal\commerce_currency_resolver\PriceExchangerCalculator $currency_calculator */ | |
$currency_calculator = \Drupal::service('commerce_currency_resolver.calculator'); | |
$local_price = $currency_calculator->priceConversion($price_from, $currency_code); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// We have two methods For controlling prices: | |
// | |
// Price resolvers: | |
// * Using weights the first to resolve the price is the one used. | |
// * You can't have two resolvers used on a single price so if you are on a multi-currency site this will be an issue. | |
// * Resolvers set the base price | |
// | |
// Adjustments: | |
// You can have multiple adjustments per order line. | |
// The adjustments themselves are a part of the order line so you can use those and the base price to do calculations, like remove the VAT element of an order. | |
// Using Price resolvers (notes) | |
// ============================ | |
// Create the service - check what other price resolvers you have on the system and set the weight acordingly. | |
// Resolver that needs currency conversion | |
// Make sure you add the following two services to your class: 'commerce_currency_resolver.current_currency' & 'commerce_currency_resolver.calculator' | |
// After calculating the price add: | |
$resolved_currency = $this->currentCurrency->getCurrency(); | |
if ($resolved_currency !== $price->getCurrencyCode()) { | |
$converted_price = $this->priceExchanger->priceConversion($price, $resolved_currency); | |
return $converted_price; | |
} | |
else { | |
return $price; | |
} | |
// Using Adjustments | |
// ==================== | |
// Adjustments are added usin a Order processor service (commerce_order.order_processor) | |
// Below is a simple example from commerce_order_test. | |
// For more complaxexamples see "class PromotionOrderProcessor" and "class TaxOrderProcessor". | |
// commerce_order_test_services.yml file | |
commerce_order_test.test_adjustment_processor: | |
class: Drupal\commerce_order_test\TestAdjustmentProcessor | |
tags: | |
- { name: commerce_order.order_processor, priority: 500, adjustment_type: test_adjustment_type } | |
// TestAdjustmentProcessor.php | |
namespace Drupal\commerce_order_test; | |
use Drupal\commerce_order\Adjustment; | |
use Drupal\commerce_order\Entity\OrderInterface; | |
use Drupal\commerce_order\OrderProcessorInterface; | |
use Drupal\commerce_price\Price; | |
/** | |
* Adds order and order item adjustments for testing purposes. | |
*/ | |
class TestAdjustmentProcessor implements OrderProcessorInterface { | |
/** | |
* {@inheritdoc} | |
*/ | |
public function process(OrderInterface $order) { | |
foreach ($order->getItems() as $order_item) { | |
// Add adjustment for PriceCalculatorTest. | |
if ($order->getEmail() == 'user2@example.com') { | |
$order_item->addAdjustment(new Adjustment([ | |
'type' => 'test_adjustment_type', | |
'label' => '$2.00 fee', | |
'amount' => new Price('2.00', 'USD'), | |
])); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment