カラーミーAPIを使う(発送データ作成)

カラーミーの標準機能で、配送サービス業者に依頼する人達はどうしているのかな?
手作業だろうか。

ここでは「未発送かつ入金済み」の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);

質問は勘弁してください。答えている時間はないです。
ソース全体出ているだけでも例はないと思います。

コメント