カラーミーの標準機能で、配送サービス業者に依頼する人達はどうしているのかな?
手作業だろうか。
ここでは「未発送かつ入金済み」のCSVデータをAPIを利用して作ってみる。
再びカラーミーAPIの認証
以前、カラーミーでどれだけの商品を受注したか個数を知りたくてアプリを作った。
再び認証について
すでに動くプログラムをひとつもっているので、認証についてリマインドしてみた。
カラーミーは2013年10月から全プランでAPI利用可能となった、というアナウンスがされているけれども、作業上で意味するところは管理画面の「アカウント設定」「カラーミーアプリ開発」画面で簡単にClient_id, client_secretを入手できるようになった、ということだ。
そして、redirect URLだがここに書くべきPHPプログラムは認証トークンを入手するだけのものであり、アプリケーションごとに作らなくてよい。もっともプログラム内にclient_idとclient_secretを記載するので、同時に動作させることはできないが、使い回して一向に構わないのだ。
言い換えると、アプリケーションとして動かすPHPのプログラム名とredirect URLはなぁんの関係もない。入手したトークンさえアプリケーションプログラムがもっていれば問題なくAPIを実行できる。
以下が汎用的なトークン入手プログラム
<?php
$params = array(
'client_id' => 管理画面からコピペ,
'client_secret' => 管理画面からコピペ,
'code' => $code,
'grant_type' => 'authorization_code',
'redirect_uri' => 管理画面からコピペ
);
$request_options = array(
'http' => array(
'method' => 'POST',
'content' => http_build_query($params)
)
);
$context = stream_context_create($request_options);
$token_url = 'https://api.shop-pro.jp/oauth/token';
$response_body = file_get_contents($token_url, false, $context);
echo $response_body;//サンプルに追加
これで得られたトークンはタイムアウトなしで使える。
で、次のようなプログラムを作った。解説は省略。それよりも、全部が掲載されていることのほうが参考になるでしょう?
なお、コード全体はUTF-8で作成しています。
<?php
// カラーミー認証
function set_up($code){
$request_options = array(
'http' => array(
'method' => 'GET',
'header'=> 'Authorization: Bearer '.$code."\r\n",
'ignore_errors' => true, // i want to get http status code.
)
);
$context = stream_context_create($request_options);
return $context;
}
// IDを集める
// 条件 not sent, paid, active, id, trans, offset
function request_sales($context, $lines, $offset){
$url = 'https://api.shop-pro.jp/v1/sales.json';
$request = '?delivered=false&paid=true&canceled=false&after=2015-01-01&fields=id&limit='.$lines.'&offset='.$offset;
$response_body = file_get_contents($url.$request, false, $context);
$pos = strpos($http_response_header[0],'200');
if ($pos === false ){ // usually don't come here.
print_r($response_body);
return NULL;
}
$response_json = json_decode($response_body, true);// associated array.
return $response_json['sales'];
} // end function.
// 各IDのデータをピックアップ
// details (product_d, product_name), sale_deliveries(name,postal, address1,addess2,memo)
function request_detail($context, $trxid){
$result = array();
$result['id'] = $trxid;
$url = 'https://api.shop-pro.jp/v1/sales/' ;
$request = $trxid . '.json';
$response_body = file_get_contents($url.$request, false, $context);
$response_json = json_decode($response_body, true);
// データがない時のエラーハンドリング
$pos = strpos($http_response_header[0],'200');
if ($pos === false ){ //usually we don't see this message.
print_r($response_json);
return NULL;
}
// トランザクション
$delivery = $response_json['sale']['sale_deliveries'][0];
unset($delivery['detail_ids']); // これは配列なのでうざいので消す
$required = array('name', 'postal', 'address1', 'address2', 'tel', 'memo');
foreach ($delivery as $key => $row){
if ( in_array($key, $required, true)){
$result[$key] = $row;
}
} // end foreach
// 商品詳細リスト
$details = $response_json['sale']['details'];
$required = array('product_id', 'product_name', 'product_num');
$pcount = 0;
foreach ($details as $detail){ // 複数商品をproduc1,product2に
$pcount++;
foreach ($detail as $key => $row){ // それぞれの商品のキー
if (in_array($key, $required, true)){
$result['product'.$pcount][$key] = $row ;
}
}
}
return $result;
} // end function.
// CSV作る。ここは需要によってかわるのでお好きに
function convert_csv($delivery){
$data = array();
$data[0] = $delivery['id'];
$data[1] = '0';
$data[2] = $delivery['tel'];
$data[3] = $delivery['postal'];
$data[4] = $delivery['address1'];
$data[5] = $delivery['address2'];
$data[6] = $delivery['name'];
$data[7] = "株)マインド・クラフト";
$data[8] = $delivery['product1']['product_id'].":".
mb_substr($delivery['product1']['product_name'],0,5).
"x".$delivery['product1']['product_num'];
if (isset($delivery['product2'])){
$data[9] = $delivery['product2']['product_id'].":".
mb_substr($delivery['product2']['product_name'],0,5).
"x".$delivery['product2']['product_num'];
} else {
$data[9] = " ";
}
if (isset($delivery['product3'])){
$data[10] = $delivery['product3']['product_id'].":".
mb_substr($delivery['product3']['product_name'],0,5).
"x".$delivery['product3']['product_num'];
} else {
$data[10] = " ";
}
// Memo内改行コードを抜く
$data[11] = str_replace(array("\r\n", "\r", "\n"), '', $delivery['memo']);
return implode(",", $data);
} // end of product_list
//---- Main ----
header("Content-Type:text/html; charset=UTF-8"); // force chars UTF-8
header("Content-TYpe: application/force-download");
$context = set_up('xxxxxxxxxxxxxトークンxxxxxxxxxxxxxxxxx');
// Phase 1: get trxs.
$offset = 0;
$lines = 40;
$trxids = array();
while(true){
$salesdata = request_sales($context, $lines, $offset);
foreach ($salesdata as $key => $row){
array_push($trxids, $row['id'] );
}
if ( count($salesdata) < $lines ) { // may be last call.
break;
} else { // should get next entries
$offset += $lines;
}
}
// Phase 2: get detail.
$deliverydata = array();
$filename = "mindcraft". date("Ymd") . ".csv"; // ファイル名
$fp = fopen($filename, "w");
$header = "種類,,,,,,,メモ"; // CSVヘッダー
$sjis_header = mb_convert_encoding($header, 'SJIS-win', 'UTF-8');
@fwrite($fp, $sjis_header."\n");
foreach ($trxids as $trxid){
$deliverydata = request_detail($context, $trxid);
// echo "<pre>";print_r($deliverydata);echo "</pre>";
$csvdata = convert_csv($deliverydata);
// excelで処理するためにはS-JISにしておくことがベスト
$sjis_csvdata = mb_convert_encoding($csvdata, 'SJIS-win', 'UTF-8');
@fwrite($fp, $sjis_csvdata."\n");
}
fclose($fp);
// ダウンロードするためのヘッダー
header('Content-Length: '. filesize($filename));
header('Content-disposition: attachment; filename="'.$filename.'"');
readfile($filename);
質問は勘弁してください。答えている時間はないです。
ソース全体出ているだけでも例はないと思います。




