Update README.md

This commit is contained in:
Geoffrey K Taylor
2020-05-11 21:22:28 -04:00
committed by Geoff Taylor
parent 6329da7af0
commit 85a935d7cb
5 changed files with 632 additions and 176 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
<a href="https://woographql.axistaylor.com/" target="_blank">Docs</a> • <a href="https://www.axistaylor.com" target="_blank">AxisTaylor</a> • <a href="https://wpgql-slack.herokuapp.com/" target="_blank">Join Slack</a>
[![Actions Status](https://github.com/wp-graphql/wp-graphql-woocommerce/workflows/WordPress%20Coding%20Standards/badge.svg)](https://github.com/wp-graphql/wp-graphql-woocommerce/actions?query=workflow%3A%22WordPress+Coding+Standards%22) [![Coverage Status](https://coveralls.io/repos/github/wp-graphql/wp-graphql-woocommerce/badge.svg?branch=develop)](https://coveralls.io/github/wp-graphql/wp-graphql-woocommerce?branch=develop) [![Financial Contributors on Open Collective](https://opencollective.com/woographql/all/badge.svg?label=financial+contributors)](https://opencollective.com/woographql) [![Actions Status](https://github.com/wp-graphql/wp-graphql-woocommerce/workflows/Testing%20Integration/badge.svg)](https://github.com/wp-graphql/wp-graphql-woocommerce/actions?query=workflow%3A%22Testing+Integration%22)
[![Actions Status](https://github.com/wp-graphql/wp-graphql-woocommerce/workflows/Testing%20Integration/badge.svg)](https://github.com/wp-graphql/wp-graphql-woocommerce/actions?query=workflow%3A%22Testing+Integration%22) [![Actions Status](https://github.com/wp-graphql/wp-graphql-woocommerce/workflows/WordPress%20Coding%20Standards/badge.svg)](https://github.com/wp-graphql/wp-graphql-woocommerce/actions?query=workflow%3A%22WordPress+Coding+Standards%22) [![Coverage Status](https://coveralls.io/repos/github/wp-graphql/wp-graphql-woocommerce/badge.svg?branch=develop)](https://coveralls.io/github/wp-graphql/wp-graphql-woocommerce?branch=develop) [![Financial Contributors on Open Collective](https://opencollective.com/woographql/all/badge.svg?label=financial+contributors)](https://opencollective.com/woographql)
## Quick Install
1. Install & activate [WooCommerce](https://woocommerce.com/)
+2
View File
@@ -149,6 +149,8 @@ configure_wordpress() {
setup_woocommerce() {
echo "Installing & Activating WooCommerce"
wp plugin install woocommerce --activate
echo "Installing & Activating WooCommerce-Gateway-Stripe"
wp plugin install woocommerce-gateway-stripe --activate
}
setup_wpgraphql() {
@@ -525,6 +525,11 @@ class Checkout_Mutation {
throw new UserError( __( 'Unable to create order.', 'wp-graphql-woocommerce' ) );
}
// Add meta data.
if ( ! empty( $input['metaData'] ) ) {
self::add_order_meta( $order_id, $input['metaData'], $input, $context );
}
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
do_action( 'woocommerce_checkout_order_processed', $order_id, $data, $order );
@@ -633,7 +638,7 @@ class Checkout_Mutation {
if ( $meta_data ) {
foreach ( $meta_data as $meta ) {
$order->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' );
$order->add_meta_data( $meta['key'], $meta['value'] );
}
}
-5
View File
@@ -146,11 +146,6 @@ class Checkout {
throw new UserError( $order_id->get_error_message( 'checkout-error' ) );
}
// Add meta data.
if ( ! empty( $input['metaData'] ) ) {
Checkout_Mutation::add_order_meta( $order_id, $input['metaData'], $input, $context, $info );
}
/**
* Action called after checking out.
*
@@ -2,7 +2,7 @@
use WPGraphQL\Type\WPEnumType;
class CheckoutMutationsTest extends \Codeception\TestCase\WPTestCase {
class CheckoutMutationTest extends \Codeception\TestCase\WPTestCase {
public function setUp() {
// before
parent::setUp();
@@ -26,7 +26,7 @@ class CheckoutMutationsTest extends \Codeception\TestCase\WPTestCase {
update_option( 'woocommerce_calc_taxes', 'yes' );
update_option( 'woocommerce_tax_round_at_subtotal', 'no' );
// Enable payment gateway.
// Enable payment gateways.
update_option(
'woocommerce_bacs_settings',
array(
@@ -38,6 +38,32 @@ class CheckoutMutationsTest extends \Codeception\TestCase\WPTestCase {
)
);
update_option(
'woocommerce_stripe_settings',
array(
'enabled' => 'yes',
'title' => 'Credit Card (Stripe)',
'description' => 'Pay with your credit card via Stripe',
'webhook' => '',
'testmode' => 'yes',
'test_publishable_key' => STRIPE_API_PUBLISHABLE_KEY,
'test_secret_key' => STRIPE_API_SECRET_KEY,
'test_webhook_secret' => '',
'publishable_key' => '',
'secret_key' => '',
'webhook_secret' => '',
'inline_cc_form' => 'no',
'statement_descriptor' => '',
'capture' => 'yes',
'payment_request' => 'yes',
'payment_request_button_type' => 'buy',
'payment_request_button_theme' => 'dark',
'payment_request_button_height' => '44',
'saved_cards' => 'yes',
'logging' => 'no',
)
);
// Additional cart fees.
add_action(
'woocommerce_cart_calculate_fees',
@@ -76,176 +102,178 @@ class CheckoutMutationsTest extends \Codeception\TestCase\WPTestCase {
parent::tearDown();
}
private function checkout( $input ) {
$mutation = '
mutation checkout( $input: CheckoutInput! ) {
checkout( input: $input ) {
clientMutationId
order {
id
orderId
currency
orderVersion
date
modified
status
discountTotal
discountTax
shippingTotal
shippingTax
cartTax
total
totalTax
subtotal
orderNumber
orderKey
createdVia
pricesIncludeTax
parent {
private function checkout( $input, $mutation = null ) {
if ( ! $mutation ) {
$mutation = '
mutation checkout( $input: CheckoutInput! ) {
checkout( input: $input ) {
clientMutationId
order {
id
orderId
currency
orderVersion
date
modified
status
discountTotal
discountTax
shippingTotal
shippingTax
cartTax
total
totalTax
subtotal
orderNumber
orderKey
createdVia
pricesIncludeTax
parent {
id
}
customer {
id
}
customerIpAddress
customerUserAgent
customerNote
billing {
firstName
lastName
company
address1
address2
city
state
postcode
country
email
phone
}
shipping {
firstName
lastName
company
address1
address2
city
state
postcode
country
}
paymentMethod
paymentMethodTitle
transactionId
dateCompleted
datePaid
cartHash
shippingAddressMapUrl
hasBillingAddress
hasShippingAddress
isDownloadPermitted
needsShippingAddress
hasDownloadableItem
downloadableItems {
nodes {
url
accessExpires
downloadId
downloadsRemaining
name
product {
productId
}
download {
downloadId
}
}
}
needsPayment
needsProcessing
metaData {
key
value
}
couponLines {
nodes {
itemId
orderId
code
discount
discountTax
coupon {
id
}
}
}
feeLines {
nodes {
itemId
orderId
amount
name
taxStatus
total
totalTax
taxClass
}
}
shippingLines {
nodes {
itemId
orderId
methodTitle
total
totalTax
taxClass
}
}
taxLines {
nodes {
rateCode
label
taxTotal
shippingTaxTotal
isCompound
taxRate {
rateId
}
}
}
lineItems {
nodes {
productId
variationId
quantity
taxClass
subtotal
subtotalTax
total
totalTax
taxStatus
product {
... on SimpleProduct {
id
}
... on VariableProduct {
id
}
}
variation {
id
}
}
}
}
customer {
id
}
customerIpAddress
customerUserAgent
customerNote
billing {
firstName
lastName
company
address1
address2
city
state
postcode
country
email
phone
}
shipping {
firstName
lastName
company
address1
address2
city
state
postcode
country
}
paymentMethod
paymentMethodTitle
transactionId
dateCompleted
datePaid
cartHash
shippingAddressMapUrl
hasBillingAddress
hasShippingAddress
isDownloadPermitted
needsShippingAddress
hasDownloadableItem
downloadableItems {
nodes {
url
accessExpires
downloadId
downloadsRemaining
name
product {
productId
}
download {
downloadId
}
}
}
needsPayment
needsProcessing
metaData {
key
value
}
couponLines {
nodes {
itemId
orderId
code
discount
discountTax
coupon {
id
}
}
}
feeLines {
nodes {
itemId
orderId
amount
name
taxStatus
total
totalTax
taxClass
}
}
shippingLines {
nodes {
itemId
orderId
methodTitle
total
totalTax
taxClass
}
}
taxLines {
nodes {
rateCode
label
taxTotal
shippingTaxTotal
isCompound
taxRate {
rateId
}
}
}
lineItems {
nodes {
productId
variationId
quantity
taxClass
subtotal
subtotalTax
total
totalTax
taxStatus
product {
... on SimpleProduct {
id
}
... on VariableProduct {
id
}
}
variation {
id
}
}
}
result
redirect
}
customer {
id
}
result
redirect
}
}
';
';
}
$actual = graphql(
array(
@@ -258,8 +286,46 @@ class CheckoutMutationsTest extends \Codeception\TestCase\WPTestCase {
return $actual;
}
private function create_stripe_customer( $email ) {
$customer = \Stripe\Customer::create( array( 'email' => $email ) );
// use --debug flag to view.
codecept_debug( $customer );
return $customer;
}
private function create_stripe_source( $customer ) {
$source = \Stripe\Customer::createSource(
$customer['id'],
array( 'source' => 'tok_visa')
);
// use --debug flag to view.
codecept_debug( $source );
return $source;
}
private function create_stripe_payment_intent( $amount, $customer ) {
$payment_intent = \Stripe\PaymentIntent::create(
array(
'amount' => $amount,
'currency' => 'gbp',
'payment_method_types' => ['card'],
'customer' => $customer['id'],
'payment_method' => $customer['invoice_settings']['default_payment_method'],
)
);
// use --debug flag to view.
codecept_debug( $payment_intent );
return $payment_intent;
}
// tests
public function testCheckoutOrderMutation() {
public function testCheckoutMutation() {
wp_set_current_user( $this->simple_customer );
$variable = $this->variation->create( $this->product->create_variable() );
$product_ids = array(
@@ -466,7 +532,7 @@ class CheckoutMutationsTest extends \Codeception\TestCase\WPTestCase {
$this->assertEquals( $expected, $actual );
}
public function testCheckoutOrderMutationWithNewAccount() {
public function testCheckoutMutationWithNewAccount() {
$variable = $this->variation->create( $this->product->create_variable() );
$product_ids = array(
$this->product->create_simple(),
@@ -657,7 +723,7 @@ class CheckoutMutationsTest extends \Codeception\TestCase\WPTestCase {
$this->assertEquals( $expected, $actual );
}
public function testCheckoutOrderMutationWithNoAccount() {
public function testCheckoutMutationWithNoAccount() {
update_option( 'woocommerce_enable_guest_checkout', 'yes' );
$variable = $this->variation->create( $this->product->create_variable() );
$product_ids = array(
@@ -852,7 +918,7 @@ class CheckoutMutationsTest extends \Codeception\TestCase\WPTestCase {
$this->assertEquals( $expected, $actual );
}
public function testCheckoutOrderMutationWithPrepaidOrder() {
public function testCheckoutMutationWithPrepaidOrder() {
update_option( 'woocommerce_enable_guest_checkout', 'yes' );
$product_ids = array(
$this->product->create_simple(
@@ -1033,4 +1099,392 @@ class CheckoutMutationsTest extends \Codeception\TestCase\WPTestCase {
$this->assertEquals( $expected, $actual );
}
public function testCheckoutMutationWithStripe() {
wp_set_current_user( $this->simple_customer );
$variable = $this->variation->create( $this->product->create_variable() );
$product_ids = array(
$this->product->create_simple(),
$this->product->create_simple(),
$variable['product'],
);
$coupon = new WC_Coupon(
$this->coupon->create( array( 'product_ids' => $product_ids ) )
);
WC()->cart->add_to_cart( $product_ids[0], 3 );
WC()->cart->add_to_cart( $product_ids[1], 6 );
WC()->cart->add_to_cart( $product_ids[2], 2, $variable['variations'][0] );
WC()->cart->apply_coupon( $coupon->get_code() );
$amount = (int) floatval( WC()->cart->get_cart_contents_total() + WC()->cart->get_cart_contents_tax() ) * 100;
$stripe_customer = $this->create_stripe_customer( 'superfreak500@gmail.com' );
$stripe_source = $this->create_stripe_source( $stripe_customer );
$payment_intent = $this->create_stripe_payment_intent( $amount, $stripe_customer );
$input = array(
'clientMutationId' => 'someId',
'paymentMethod' => 'stripe',
'shippingMethod' => 'flat rate',
'billing' => array(
'firstName' => 'May',
'lastName' => 'Parker',
'address1' => '20 Ingram St',
'city' => 'New York City',
'state' => 'NY',
'postcode' => '12345',
'country' => 'US',
'email' => 'superfreak500@gmail.com',
'phone' => '555-555-1234',
),
'shipping' => array(
'firstName' => 'May',
'lastName' => 'Parker',
'address1' => '20 Ingram St',
'city' => 'New York City',
'state' => 'NY',
'postcode' => '12345',
'country' => 'US',
),
'metaData' => array(
array(
'key' => '_stripe_source_id',
'value' => $stripe_source['id'],
),
array(
'key' => '_stripe_customer_id',
'value' => $stripe_customer['id'],
),
array(
'key' => '_stripe_intent_id',
'value' => $payment_intent['id'],
),
)
);
// Remove "metaData" value field and "redirect" link from the mutation output.
$modified_mutation = '
mutation checkout( $input: CheckoutInput! ) {
checkout( input: $input ) {
clientMutationId
order {
id
orderId
currency
orderVersion
date
modified
status
discountTotal
discountTax
shippingTotal
shippingTax
cartTax
total
totalTax
subtotal
orderNumber
orderKey
createdVia
pricesIncludeTax
parent {
id
}
customer {
id
}
customerIpAddress
customerUserAgent
customerNote
billing {
firstName
lastName
company
address1
address2
city
state
postcode
country
email
phone
}
shipping {
firstName
lastName
company
address1
address2
city
state
postcode
country
}
paymentMethod
paymentMethodTitle
transactionId
dateCompleted
datePaid
cartHash
shippingAddressMapUrl
hasBillingAddress
hasShippingAddress
isDownloadPermitted
needsShippingAddress
hasDownloadableItem
downloadableItems {
nodes {
url
accessExpires
downloadId
downloadsRemaining
name
product {
productId
}
download {
downloadId
}
}
}
needsPayment
needsProcessing
metaData {
key
}
couponLines {
nodes {
itemId
orderId
code
discount
discountTax
coupon {
id
}
}
}
feeLines {
nodes {
itemId
orderId
amount
name
taxStatus
total
totalTax
taxClass
}
}
shippingLines {
nodes {
itemId
orderId
methodTitle
total
totalTax
taxClass
}
}
taxLines {
nodes {
rateCode
label
taxTotal
shippingTaxTotal
isCompound
taxRate {
rateId
}
}
}
lineItems {
nodes {
productId
variationId
quantity
taxClass
subtotal
subtotalTax
total
totalTax
taxStatus
product {
... on SimpleProduct {
id
}
... on VariableProduct {
id
}
}
variation {
id
}
}
}
}
customer {
id
}
result
}
}
';
/**
* Assertion One
*
* Test mutation and input.
*/
$actual = $this->checkout( $input, $modified_mutation );
// use --debug flag to view.
codecept_debug( $actual );
$this->assertArrayHasKey('data', $actual );
$this->assertArrayHasKey('checkout', $actual['data'] );
$this->assertArrayHasKey('order', $actual['data']['checkout'] );
$this->assertArrayHasKey('id', $actual['data']['checkout']['order'] );
$order = \WC_Order_Factory::get_order( $actual['data']['checkout']['order']['orderId'] );
// Get Available payment gateways.
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
$expected = array(
'data' => array(
'checkout' => array(
'clientMutationId' => 'someId',
'order' => array_merge(
$this->order->print_query( $order->get_id() ),
array(
'metaData' => array(
array( 'key' => 'is_vat_exempt', ),
array( 'key' => '_stripe_source_id' ),
array( 'key' => '_stripe_customer_id' ),
array( 'key' => '_stripe_intent_id' ),
array( 'key' => '_stripe_charge_captured' ),
array( 'key' => '_stripe_fee' ),
array( 'key' => '_stripe_net' ),
array( 'key' => '_stripe_currency' ),
),
'couponLines' => array(
'nodes' => array_reverse(
array_map(
function( $item ) {
return array(
'itemId' => $item->get_id(),
'orderId' => $item->get_order_id(),
'code' => $item->get_code(),
'discount' => ! empty( $item->get_discount() ) ? $item->get_discount() : null,
'discountTax' => ! empty( $item->get_discount_tax() ) ? $item->get_discount_tax() : null,
'coupon' => null,
);
},
$order->get_items( 'coupon' )
)
),
),
'feeLines' => array(
'nodes' => array_reverse(
array_map(
function( $item ) {
return array(
'itemId' => $item->get_id(),
'orderId' => $item->get_order_id(),
'amount' => $item->get_amount(),
'name' => $item->get_name(),
'taxStatus' => strtoupper( $item->get_tax_status() ),
'total' => $item->get_total(),
'totalTax' => ! empty( $item->get_total_tax() ) ? $item->get_total_tax() : null,
'taxClass' => ! empty( $item->get_tax_class() )
? WPEnumType::get_safe_name( $item->get_tax_class() )
: 'STANDARD',
);
},
$order->get_items( 'fee' )
)
),
),
'shippingLines' => array(
'nodes' => array_reverse(
array_map(
function( $item ) {
return array(
'itemId' => $item->get_id(),
'orderId' => $item->get_order_id(),
'methodTitle' => $item->get_method_title(),
'total' => $item->get_total(),
'totalTax' => !empty( $item->get_total_tax() )
? $item->get_total_tax()
: null,
'taxClass' => ! empty( $item->get_tax_class() )
? $item->get_tax_class() === 'inherit'
? WPEnumType::get_safe_name( 'inherit cart' )
: WPEnumType::get_safe_name( $item->get_tax_class() )
: 'STANDARD'
);
},
$order->get_items( 'shipping' )
)
),
),
'taxLines' => array(
'nodes' => array_reverse(
array_map(
function( $item ) {
return array(
'rateCode' => $item->get_rate_code(),
'label' => $item->get_label(),
'taxTotal' => $item->get_tax_total(),
'shippingTaxTotal' => $item->get_shipping_tax_total(),
'isCompound' => $item->is_compound(),
'taxRate' => array( 'rateId' => $item->get_rate_id() ),
);
},
$order->get_items( 'tax' )
)
),
),
'lineItems' => array(
'nodes' => array_values(
array_map(
function( $item ) {
return array(
'productId' => $item->get_product_id(),
'variationId' => ! empty( $item->get_variation_id() )
? $item->get_variation_id()
: null,
'quantity' => $item->get_quantity(),
'taxClass' => ! empty( $item->get_tax_class() )
? strtoupper( $item->get_tax_class() )
: 'STANDARD',
'subtotal' => ! empty( $item->get_subtotal() ) ? $item->get_subtotal() : null,
'subtotalTax' => ! empty( $item->get_subtotal_tax() ) ? $item->get_subtotal_tax() : null,
'total' => ! empty( $item->get_total() ) ? $item->get_total() : null,
'totalTax' => ! empty( $item->get_total_tax() ) ? $item->get_total_tax() : null,
'taxStatus' => strtoupper( $item->get_tax_status() ),
'product' => array( 'id' => $this->product->to_relay_id( $item->get_product_id() ) ),
'variation' => ! empty( $item->get_variation_id() )
? array(
'id' => $this->variation->to_relay_id( $item->get_variation_id() )
)
: null,
);
},
$order->get_items()
)
),
),
)
),
'customer' => array(
'id' => $this->customer->to_relay_id( $order->get_customer_id() )
),
'result' => 'success',
),
)
);
$this->assertEquals( $expected, $actual );
}
}