I already done with https://acp.sample.ph/wc/v3/order created in PHP but the response of the API doesn't show the bank/account details for Bank account transfer (BACS). I am using the package automattic/woocommerce for fetching the API. This API I fetch is from WordPress woocommerce. Here's my sample code below.
$woocommerce = new Client(
'https://acp.sample.ph',
$credential['key'],
$credential['secrete'],
[
'wp_api' => true,
'version' => 'wc/v3',
'query_string_auth' => true
]
);
$data = array(
"order_id"=>"717",
"payment_method"=>"bacs"
);
$accounts = $woocommerce->post('process_payment', $data);
echo '<pre>';
print_r($accounts);
echo '</pre>';
You might need to create own endpoint or alter the Order API response
Can you try this ---
function prefix_wc_rest_prepare_order_object( $response, $object, $request ) {
// Get the value
$bacs_info = get_option( 'woocommerce_bacs_accounts');
$response->data['bacs_info'] = $bacs_info;
return $response;
}
add_filter( 'woocommerce_rest_prepare_shop_order_object', 'prefix_wc_rest_prepare_order_object', 10, 3 );
Related
I'm currently trying to create an API which will be used to create an app
To do this I need a custom endpoint which should be accessed only from a logged user, which is currently done using this code:
register_rest_route( 'wp/v2', 'private/me',array(
'methods' => WP_REST_Server::READABLE,
'callback' => 'get_private'
));
function get_private($request) {
$user = (array) wp_get_current_user();
$user["data"] = (array) $user["data"];
unset($user['data']['user_pass']);
// $user = get_user_by('id', 13);
if (empty($user)) {
return new WP_Error( 'empty_category', 'there is no post in this category', array('status' => 404) );
}
$response = new WP_REST_Response($user['data']);
$response->set_status(200);
return $response;
}
Currently it return an user object without 'user_pass'
Then when I use the 'register_rest_field' function, I get nothing (the function work if set on any default api user endpoint
register_rest_field('private/me',
'rank_number',
array(
'get_callback' => 'get_rank_number',
'update_callback' => null,
'schema' => null
)
);
function get_rank_number ( $user ) {
return (int) get_user_meta($user['id'], 'ck_user_ranking_score_number', true);
}
The thing is, I don't know how to make the route read the list of the registered rest fields nor if it's supposed to be done like that
Currently, I'm trying to make it by extending the WP_REST_Controller class since it looks like it could work
Can someone help me understand how the API work or how it is supposed to be used ? :/
In case anyone have the same problem, a wordpress user answered my post on their forum,
Solution:
The var $wp_rest_additional_fields, I can't find anything about it in the documentation, but at least the var really exist in the global scope
So with this code everything's ok
global $wp_rest_additional_fields;
foreach($wp_rest_additional_fields['private/me'] as $key => $value){
$user_data[$key] = call_user_func($value['get_callback'], $user['data']);
}
I am creating a custom endpoint in wordpress, which should do the following:
1. Create the path (done)
2. call a function, which:
2.1. Gets all the products from WooCommerce and stores them in an array (done)
2.2. Compares the products on WooCommerce with products from an external database and if there is any difference in data, get updated (PUT) by the data from the external DB
2.3. If some products exist on the external DB but do not exist on WooCommerce, create them on WooCommerce (POST)
I have managed to get all the data from WooCommerce via wc_get_products ($args) but I cannot find how to write the PUT and the POST method to update or create products.
If I use Automatic/WooCommerce to push or put products from a standalone file (not from the custom endpoint) works, but if I keep the Automatic/WooCommerce on the custom endpoint it tells me the following:
Failed to connect to localhost port 8000: Connection refused in /var/www/html/wp-content/plugins/wl-api/vendor/automattic/woocommerce/src/WooCommerce/HttpClient/HttpClient.php on line 417
which makes total sense because from the custom endpoint I am already connected to WooCommerce and the Automatic/WooCommerce would attempt to connect again. So are there any methods like wc_get_products but for PUT and PUSH?
//CUSTOM ENDPOINT PHP FILE
add_action('rest_api_init', 'customEndpoint');
function customEndpoint() {
register_rest_route('endpoint', '/transfer', array(
'methods' => 'GET',
'callback' => 'get_data',
));
}
function get_data() {
include "updateOrCreate.php";
}
//updateOrCreate.php
require 'vendor/autoload.php';
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require 'vendor/guzzlehttp/guzzle/src/Client.php';
use Automattic\WooCommerce;
//-----------Connect to the External DB----------
$baseUrl=...;
$externalClient = new GuzzleHttp\Client();
$res = $externalClient->request('GET', $baseUrl, [
"query" => ['fields' => $fields, 'aktiv' => true],
'auth' => ['...', '...']
]);
$articles = json_decode($res->getBody());
//-----------Connect to WooCommerce DB
$wooKey= "...";
$wooSecret= "...";
$wooCommerceBaseUrl = "http://localhost:8000";
$wooCommerceClient = new WooCommerce\Client($wooCommerceBaseUrl,
$wooKey, $wooSecret,
[
'wp_api' => true,
'version' => 'wc/v3',
]
);
//GET all products from WooCommerce
$args = array(
'status' => 'publish',
'limit' => -1,
);
$wooExistingProducts = wc_get_products($args);
$productsForWoo= [];
//check if there are no products on woocommerce:
if(empty($wooExistingProducts)){
foreach ($articles as &$article){
//Create the necessary template to initialize the connections between external products and woocommerce product template
$wooTemplate = [
...
];
array_push($productsForWoo, $wooTemplate);
//CREATE BATCHES OF 10
if(sizeof($productsForWoo) == 10){
$data = [
'create' => $productsForWoo,
];
$wooCommerceClient->post('products/batch', $data);
$productsForWoo = [];
}
}
//As there is a big chance that the last batch will have less than 10 products, push them as well to wooCommerce as a last batch
$data = [
'create' => $productsForWoo,
];
$wooCommerceClient->post('products/batch', $data);
}
// if there are existing products on woocommerce
else{
//Loop through all existing products on the external DB
foreach ($articles as &$article){
$did_match = false;
$wooTemplate = [
...
];
//loop through all products on WooCommerce
foreach ($wooExistingProducts as &$product){
//if the product id from the external db matches the id from an existing product on woocommerce
if(...){
//update that product
$wooCommerceClient->put('products/'.urlencode($product->id), $wooTemplate);
$did_match = true;
break;
}
}
//otherwise, if the product from the external db is not found on the woocommerce database, create it
if(!$did_match){
array_push($productsForWoo, $wooTemplate);
if(sizeof($productsForWoo) == 10){
$data = [
'create' => $productsForWoo,
];
$wooCommerceClient->post('products/batch', $data);
$productsForWoo = [];
}
}
}
//As there is a big chance that the last batch will have less than 10 products, push them as well to wooCommerce as a last batch
$data = [
'create' => $productsForWoo,
];
$wooCommerceClient->post('products/batch', $data);
}
I will deeply appreciate any input related to my issue. Thank you!
To get POST and PUT, you'll need to implement the methods (verbs).
You can use:
$verb = $_SERVER['REQUEST_METHOD'];
echo $verb;
... to test what HTTP request method (PUT vs GET) you're using.
Here's a SO article regarding PHP methods which I have bookmarked and often use when troubleshooting this. The code provided there is pretty clean and a great place to start.
I would like to extend the woocommerce rest api to include data of its 'booking' extension plugin. Currently this extension does not have default endpoints provided by the rest api.
So far I have created a plugin, and I've added the following code;
add_filter( 'woocommerce_rest_prepare_product', 'custom_data');
function custom_data($response, $object) {
if( empty( $response->data ) )
return $response;
$response->data['meta_data'] = get_post_meta( $object[ID], 'availability', true);
return $response;
}
When I call the end point /products only the default data outlined by woocommerce is still called my little add on is no where to be found.
I don't even know where to find the above filter as I just saw this posted on a webpage and I tried to get it to do what I wanted, don't know if this is the correct direction to go down either. Webpage: https://francescocarlucci.com/woocommerce/woocommerce-api-custom-data-default-endpoints/#more-96
The above was me trying to extend the api but I also decided to try making a custom endpoint to see if I can get my desired outcome but so far I've just made a endpoint which calls but I have no idea what to write to retrieve the data I want.
custom end point code:
function register_custom_route() {
register_rest_route( 'ce/v1', '/bookable',
array(
'methods' => 'GET',
'callback' => 'get_bookable'
)
);
}
function get_bookable( ) {
return array( 'custom' => 'woocommerce here' );
//What code do I write here :(
}
Is there anyway I can achieve what I want under one of the above methods?
I'm quite new to dev and I'm familiar with javascript not PHP hence my need to want to use the rest api as I would like to use wordpress/woocommerce as a headless cms.
So far the closets example I've come to has been shown on this question Creating WooCommerce Custom API
Alternatively you can try the below code to extend product response of WooCommerce REST API without doing additionally, as your above hook "woocommerce_rest_prepare_product" is for v1 but currently it was v3 so the hook for the latest is below one(the below hook is from v2 controller of rest api which is extended by v3).
add_filter('woocommerce_rest_prepare_product_object', 'so54387226_custom_data', 10, 3);
function so54387226_custom_data($response, $object, $request) {
if (empty($response->data))
return $response;
$id = $object->get_id(); //it will fetch product id
$response->data['booking_meta_data'] = get_post_meta($id, 'availability', true);
return $response;
}
I tested the above code it works perfectly fine. Hope it may helps to someone who search for similar solution.
this is only part of my code. some variable not defined. and this just concept. hopefully, you can modify as per your requirement.
public function __construct() {
$this->template_url = apply_filters( 'woocommerce_template_url', 'woocommerce/'
);
$this->api_namespace = 'wc/v';
$this->base = 'home';
$this->api_version = '2';
add_action( 'woocommerce_loaded', array( $this, 'register_hooks' ) );
}
$namespace = $this->api_namespace . $this->api_version;
register_rest_route(
$namespace, '/wclogin/',
array(
'methods' => 'GET',
'callback' => array( $this, 'wc_login'),
)
);
function wc_login($request){
$user = get_user_by('email', $request["email"]);
//bad email
if(!$user){
$error = new WP_Error();
$error->add('invalid', __('<strong>ERROR</strong>: Either the email or password you entered is invalid.'));
return $error;
}
else{ //check password
if(!wp_check_password($request["password"], $user->user_pass, $user->ID)){ //bad password
$error = new WP_Error();
$error->add('invalid', __('<strong>ERROR</strong>: Either the email or password you entered is invalid.'));
return $error;
}else{
return $user; //passed
}
}
}
Just an update for those that come to this question. Now, there is a rest api for the booking extension: https://docs.woocommerce.com/document/bookings-rest-api-reference/
I am creating a WordPress plugin, and trying to pull payments details from stripe API done via third party. I have tried everything mention in this code but I am not able to pull data of Payments from stripe.
I need to fetch payment details from stripe API
https://stripe.com/docs/api/transfers?lang=php
I have tried payouts \Stripe\Payout::all() but getting empty object
Here is my code:
namespace wpmember;
class WPMember
{
public function __construct()
{
add_action( 'admin_menu', array($this, 'wpdocs_register_my_custom_menu_page') );
}
public function wpdocs_register_my_custom_menu_page()
{
add_menu_page(
'Custom Menu Title',
'custom menu',
'manage_options',
'custom-menu',
$this->connect_stripe()
);
}
public function connect_stripe()
{
require ( PLUGIN_DIR . 'vendor/autoload.php');
//echo PLUGIN_DIR . 'vendor/autoload.php';
\Stripe\Stripe::setApiKey("xxxx");
\Stripe\Stripe::setApiKey("xxxx");
$customers = \Stripe\Customer::all(["limit" => 3]);
$products = \Stripe\Product::all(["limit" => 3]);
$subscriptions = \Stripe\Subscription::all(['limit'=>3]);
$orders = \Stripe\Order::all(["limit" => 3]);
$allpayouts = \Stripe\Payout::all(["limit" => 3]);
$paymentIntent = \Stripe\PaymentIntent::all(["limit" => 3]);
//$payout = \Stripe\Payout::retrieve($allpayouts->data[0]->id);
$invoice = \Stripe\Invoice::all(["limit" => 3]);
echo "<pre>";
print_r($subscriptions);
echo "</pre>";
}
}
You seem to be fetching Payouts which are according to the Stripe API reference are the transfers from your Stripe account to your bank account. Which do not seem to be Charges object you showed on your screenshot or Transfer objects that could be fetched with \Stripe\Transfer::all().
Here you can get the payment details:
require ( PLUGIN_DIR . 'vendor/autoload.php');
\Stripe\Stripe::setApiKey("pk_test_VNbKcUGTqFIlyfIwFgizNx8h");
\Stripe\Stripe::setApiKey("sk_test_7VbuCbiZsDZjDHHlOtHeCqo7");
$charges = \Stripe\Charge::all(["limit" => 3]);
print_r($charges);
I have this existing code snippet that searches list of records specified by its RecordType (e.g. InventoryItem, SalesOrder).
$request = new GetRequest();
$request->baseRef = new RecordRef();
$request->baseRef->type = $type; //Record Type
$request->baseRef->internalId = $internalId; //Internal ID of record
$getResponse = $service->get($request);
if ( ! $getResponse->readResponse->status->isSuccess) {
return 'ERROR';
} else {
return $getResponse->readResponse->record;
}
However, it seems that there's no Shipping Item in the list in RecordType although I can pass an internal ID. My goal here was to get the shipping item details to be used in my computation for creating a sales order (needs to be displayed before submitting).
Will there be a different approach in getting the shipping item record? How?
Shipping Item record is not yet supported in Suitetalk. As an alternate solution you can create a RESTlet instead to get the Shipping Item.
I can now successfully retrieve Shipping items via RESTlets. I uploaded this first as new in the File Cabinet, then added it as a new script. NetSuite does not allow direct upload of script file when creating a new script.
// get_record.js
function get_record(datain)
{
var record = nlapiLoadRecord(datain.recordType, datain.id);
return record;
}
Then used guzzle http library to call the RESTlet.
$url = "https://rest.sandbox.netsuite.com/app/site/hosting/restlet.nl";
$client = new GuzzleHttp\Client();
$authorization = [
'NLAuth nlauth_account='.getenv('NETSUITE_ACCOUNT'),
'nlauth_email='.getenv('NETSUITE_EMAIL'),
'nlauth_signature='.getenv('NETSUITE_PASSWORD'),
'nlauth_role='.getenv('NETSUITE_ROLE')
];
$response = $client->request('GET', $url, [
'headers' => [
'Authorization' => implode(',', $authorization),
'Content-Type' => 'application/json'
],
'query' => [
'script' => '343', //script id
'deploy' => '1',
'recordType' => 'ShipItem',
'id' => '5905' // example of internal id of desired shipping item
]
]);
return json_decode($response->getBody());